#include "stdafx.h"
#include "Game.h"
#include "StackAllocator.h"



int schemecount = 6;
int currentScheme = 5;
Ogre::String qualitySchemes[] = 
{
	"VeryLow",
	"Low",
	"Medium",
	"High",
	"VeryHigh",
	"Ultra"
};
//-------------------------------------------------------------------------------------
Game::Game(Ogre::Root *root,Ogre::RenderWindow* window)
{

	mShutDown = false;
	mRoot = root;
	mWindow = window;
	//gContactAddedCallback = myContactAddedCallback;


	/*gravityVector = Ogre::Vector3(0,-9.81,0);
	bounds = Ogre::AxisAlignedBox(Ogre::Vector3 (-10000, -10000, -10000), Ogre::Vector3 (10000,  10000,  10000));*/

	PlayerBodyControlLogic* playerBodyControlLogic = new PlayerBodyControlLogic();
	controlLogics["PlayerBodyControlLogic"] = playerBodyControlLogic;


	// PlayerControlElements
	PlayerControlElement* playerControlElement = new PlayerControlElement(/*OIS::KC_E*/0, Ogre::Vector3(0, 100, 0),
		Ogre::Vector3::ZERO);
	// PlayerControlLogic
	PlayerControlLogic* playerControlLogic = new PlayerControlLogic();
	// Adding PlayerControlElements to PlayerControlLogic
	playerControlLogic->addPlayerControlElement(playerControlElement);
	// Register PlayerControlLogic
	controlLogics["PlayerControlLogic"] = playerControlLogic;

	pSystemZeroCount= 0;

	projectileCount = 0;
	maxProjectileCount = 0;

	mGameON = false;
	mGameOFF = false;
	multiplayer = false;
	rCameraUsed = false;
	customReaderUsed = false;
	gameOverHandlerUsed = false;
	gameStatus = ControlContext::PLAYING;



	/*char* noString = "";
	gameAudio = new GameAudio(0, &noString);*/
	gameAudio = (UltimateSoundSubsystem*) UltimateSubsystemRegistry::getSingletonPtr()->getSubsystem(SOUND_SUBSYSTEM);
	if(!gameAudio)
		gameAudio = new UltimateSoundMock();

	mInputSubsystem = (UltimateInputSubsystem*) UltimateSubsystemRegistry::getSingletonPtr()->getSubsystem(INPUT_SUBSYSTEM);



}
//-------------------------------------------------------------------------------------
Game::~Game(void)
{
	mSceneMgr->destroyQuery(mRaySceneQuery);
}

void Game::initGame()
{
	configure();
	createScene();
}



//-------------------------------------------------------------------------------------
void Game::createScene(void)
{



	contactReport.setSceneManager(mSceneMgr);
	contactReport.setControlSceneManager(controlSceneManager);
	contactReport.setParticleSystems(&pSystems);
	/*mNxScene->setUserContactReport(&contactReport);*/

	mCamera = mSceneMgr->createCamera("PlayerCam");

	Ogre::Viewport* vp = mWindow->addViewport(mCamera);
	vp->setBackgroundColour(Ogre::ColourValue(0,0,0));

	// Alter the camera aspect ratio to match the viewport
	mCamera->setAspectRatio(
		Ogre::Real(vp->getActualWidth()) / Ogre::Real(vp->getActualHeight()));


	mWindow->getViewport(0)->setMaterialScheme(qualitySchemes[5]);



	//mRenderer = &CEGUI::OgreRenderer::bootstrapSystem();
	//CEGUI::Imageset::setDefaultResourceGroup("Imagesets");
	//CEGUI::Font::setDefaultResourceGroup("Fonts");
	//CEGUI::Scheme::setDefaultResourceGroup("Schemes");
	//CEGUI::WidgetLookManager::setDefaultResourceGroup("LookNFeel");
	//CEGUI::WindowManager::setDefaultResourceGroup("Layouts");

	//CEGUI::SchemeManager::getSingleton().create("TaharezLook.scheme");
	//CEGUI::System::getSingleton().setDefaultMouseCursor("TaharezLook", "MouseArrow");

	//CEGUI::MouseCursor::getSingleton().setImage( CEGUI::System::getSingleton().getDefaultMouseCursor());
	////CEGUI::MouseCursor::getSingleton().hide();

	//CEGUI::WindowManager &wmgr = CEGUI::WindowManager::getSingleton();
	//CEGUI::Window *sheet = wmgr.createWindow("DefaultWindow", "CEGUIDemo/Sheet");
	//CEGUI::System::getSingleton().setGUISheet(sheet);



	/*CEGUI::Window *quit = wmgr.createWindow("TaharezLook/Button", "CEGUIDemo/QuitButton");
	quit->setText("Quit");
	quit->setAlpha(0.55);
	quit->setSize(CEGUI::UVector2(CEGUI::UDim(0.15, 0), CEGUI::UDim(0.05, 0)));
	quit->setPosition(CEGUI::UVector2(CEGUI::UDim(0.85f, 0),
	CEGUI::UDim(0.0f, 0)));
	sheet->addChildWindow(quit);

	quit->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&Game::quit, this));*/



	//mCamera->setFarClipDistance(10);



	mRaySceneQuery = mSceneMgr->createRayQuery(Ogre::Ray());



	//std::vector<Ogre::Vector3*> basePoints;
	////basePoints.push_back(new Ogre::Vector3(400,0,0));
	///*basePoints.push_back(new Ogre::Vector3(0,0,0));
	//basePoints.push_back(new Ogre::Vector3(500,0,0));
	//basePoints.push_back(new Ogre::Vector3(2000,100,200));
	//basePoints.push_back(new Ogre::Vector3(5000,1000,400));
	//basePoints.push_back(new Ogre::Vector3(8000,200,-200));
	//*/

	//basePoints.push_back(new Ogre::Vector3(0,0,0));
	//basePoints.push_back(new Ogre::Vector3(1000,0,0));
	//basePoints.push_back(new Ogre::Vector3(2000,0,0));
	//basePoints.push_back(new Ogre::Vector3(3000,0,0));
	//basePoints.push_back(new Ogre::Vector3(4000,0,0));
	//basePoints.push_back(new Ogre::Vector3(5000,0,0));
	//basePoints.push_back(new Ogre::Vector3(10000,0,0));
	///*Ogre::SceneNode *goalNode =  mSceneMgr->createSceneNode("SinbadGoalNode");
	//goalNode->setPosition(5000,0,0);
	//goalNode->setScale(5,5,5);
	//Ogre::Entity *goalEntity = mSceneMgr->createEntity("SinbadGoal","sinbad.mesh");
	//goalNode->attachObject(goalEntity);*/



	//float curveResolution = 0.01;

	//std::vector<Ogre::Vector3*> *curvePoints = CurveGenerator::generateCurve(&basePoints, curveResolution);

	//AIControlLogic *AILogic = new AIControlLogic();

	//AIGoal * goal = new AIGoal();
	//AIGoal::AIGoalRecord * goalRecord = new AIGoal::AIGoalRecord();
	//goalRecord->param= POSITION_PARAMETER;
	//VectorEntityParameter * goalParam = new VectorEntityParameter(POSITION_PARAMETER);
	//goalParam->setVectorValue(Ogre::Vector3(5000,0,0));
	//goalRecord->goal = goalParam;
	//goalRecord->negate = false;
	//goalRecord->offset = 0;
	//goalRecord->weight = 1;
	//goal->addGoalRecord(goalRecord);

	//Trigger *upTrigger = new Trigger();
	//upTrigger->addRequiement(new FreeRayReq(mRaySceneQuery,Ogre::Vector3(0,10,0), Ogre::Vector3(1,0,0),200));
	//upTrigger->addAction(new OnRailMoveAction(curvePoints));
	//upTrigger->addAction(new FreeMoveAction(Ogre::Vector3(0,1,0),10));
	//goal->addTrigger(upTrigger);

	//Trigger *downTrigger = new Trigger();
	//downTrigger->addRequiement(new FreeRayReq(mRaySceneQuery,Ogre::Vector3(0,-10,0), Ogre::Vector3(1,0,0),200));
	//downTrigger->addAction(new OnRailMoveAction(curvePoints));
	//downTrigger->addAction(new FreeMoveAction(Ogre::Vector3(0,-1,0),10));
	//goal->addTrigger(downTrigger);

	//Trigger *rigthTrigger = new Trigger();
	//rigthTrigger->addRequiement(new FreeRayReq(mRaySceneQuery,Ogre::Vector3(0,0,10), Ogre::Vector3(1,0,0),200));
	//rigthTrigger->addAction(new OnRailMoveAction(curvePoints));
	//rigthTrigger->addAction(new FreeMoveAction(Ogre::Vector3(0,0,1),10));
	//goal->addTrigger(rigthTrigger);


	//Trigger *leftTrigger = new Trigger();
	//leftTrigger->addRequiement(new FreeRayReq(mRaySceneQuery,Ogre::Vector3(0,0,-10), Ogre::Vector3(1,0,0),200));
	//leftTrigger->addAction(new OnRailMoveAction(curvePoints));
	//leftTrigger->addAction(new FreeMoveAction(Ogre::Vector3(0,0,-1),10));
	//goal->addTrigger(leftTrigger);

	//Trigger *forwardTrigger = new Trigger();
	//forwardTrigger->addRequiement(new FreeRayReq(mRaySceneQuery,Ogre::Vector3(0,0,0), Ogre::Vector3(1,0,0),200));
	//forwardTrigger->addAction(new OnRailMoveAction(curvePoints));
	//goal->addTrigger(forwardTrigger);


	//AILogic->addGoal(goal);

	//controlLogics["AIControlLogic"] = AILogic;


	//runScript("script/init.lua");





	setupCollisions();



	/*int eyeX, eyeY;
	move->getEyeDimensions(eyeX,eyeY);

	camImage = mRoot->getTextureManager()->createManual(
	"RTT",
	Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
	Ogre::TEX_TYPE_2D,
	eyeX,
	eyeY,
	0,
	Ogre::PF_B8G8R8A8);

	CEGUI::Texture &guiTex = mRenderer->createTexture(camImage);

	CEGUI::Imageset &imageSet =
	CEGUI::ImagesetManager::getSingleton().create("RTTImageset", guiTex);
	imageSet.defineImage("RTTImage",
	CEGUI::Point(0.0f, 0.0f),
	CEGUI::Size(guiTex.getSize().d_width,
	guiTex.getSize().d_height),
	CEGUI::Point(0.0f, 0.0f));

	CEGUI::Window *si = CEGUI::WindowManager::getSingleton().createWindow("TaharezLook/StaticImage", "RTTWindow");
	si->setSize(CEGUI::UVector2(CEGUI::UDim(0.0f, 320),
	CEGUI::UDim(0.0f, 240)));
	si->setPosition(CEGUI::UVector2(CEGUI::UDim(0.0f, 0),
	CEGUI::UDim(0.0f, 0)));

	si->setAlpha(0.5);
	si->setProperty("Image", CEGUI::PropertyHelper::imageToString(&imageSet.getImage("RTTImage")));

	CEGUI::System::getSingleton().getGUISheet()->addChildWindow(si);*/


	//mainHUD = new HUD();

	mMenuScript= "script/menuScene.lua";
	createMenu(mMenuScript);

	//CurveGenerator * cG = new CurveGenerator();
	//cG->addPoint(new Ogre::Vector3(0,0,0));
	//cG->addPoint(new Ogre::Vector3(50,50,0));
	//cG->addPoint(new Ogre::Vector3(30,50,-100));
	//cG->addPoint(new Ogre::Vector3(0,0,-200));
	//cG->addPoint(new Ogre::Vector3(50,100,-300));
	//
	//std::vector<Ogre::Vector3*> * points = cG->generateCurve();

	//int i =0;
	//for(std::vector<Ogre::Vector3*>::iterator iter= points->begin(); iter!=points->end(); iter++)
	//{
	//	Ogre::SceneNode * node = mSceneMgr->getRootSceneNode()->createChildSceneNode((*(*iter)));
	//	
	//	Ogre::Entity * entity = mSceneMgr->createEntity("curve"+Ogre::StringConverter::toString(i),"MeatBall.mesh");
	//	node->attachObject(entity);
	//	i++;
	//	//(*(*iter))
	//}


	/*Ogre::CompositorManager::getSingleton().addCompositor(mWindow->getViewport(0), "Negative");
	Ogre::CompositorManager::getSingleton().addCompositor(mWindow->getViewport(0), "Monochrome");
	Ogre::CompositorManager::getSingleton().addCompositor(mWindow->getViewport(0), "MotionBlur");*/


}



void Game::destroyScene(void)
{

	lua_close(LuaState);
}


// game:createMap(background = BG, mapBasePoints = Map, numberOFElements = 4, elementTypes = MapElements)
void Game::createMap(Ogre::String skyBoxName, luabind::object mapConfiguration)
{
	mSceneMgr->setSkyBox(true, skyBoxName);

	//CREATING THE SKY
	/*
	Ogre::Plane skyPlane;
	skyPlane.d = 1000;
	skyPlane.normal = Ogre::Vector3::NEGATIVE_UNIT_Y;
	mSceneMgr->setSkyPlane(true, skyPlane, BG, 1500, 5, true, 1.5f, 150,150);
	*/
	/*
	mSceneMgr->setSkyPlane(false, Ogre::Plane(), "");
	mSceneMgr->setSkyDome(false, "");
	mSceneMgr->setSkyDome(true, BG, 10.0, 1);
	//mSceneMgr->setSkyBox(true, BG, 4000);
	*/


	// game:createMap({background = "bg.orion_nebula_3"}, {mapBasePoints = Map, elementTypes = MapElements})

	//// mapBasePoints structure
	//luabind::object mapBasePoints = luabind::object_cast<luabind::object>(mapConfiguration["mapBasePoints"]);

	//// number of mapBasePoints
	//int numberOfMapBasePoints = luabind::object_cast<int>(mapBasePoints["numberOfPoints"]);

	//// Get the points to basePoints
	//std::vector<Ogre::Vector3*> mapBPoints;
	//for( int i = 1; i <= numberOfMapBasePoints; i++)
	//{
	//	// Get the ith point
	//	luabind::object luaPoint = luabind::object_cast<luabind::object>(mapBasePoints["point" + Ogre::StringConverter::toString(i)]);
	//	float x = luabind::object_cast<float>(luaPoint["x"]);
	//	float y = luabind::object_cast<float>(luaPoint["y"]);
	//	float z = luabind::object_cast<float>(luaPoint["z"]);
	//	Ogre::Vector3* point = new Ogre::Vector3(x,y,z);

	//	// Add the point
	//	mapBPoints.push_back(point);
	//}

	float resolution = luabind::object_cast<float>(mapConfiguration["resolution"]);
	float percent = luabind::object_cast<float>(mapConfiguration["percent"]);
	int maxElements = luabind::object_cast<float>(mapConfiguration["maxElements"]);
	int countToMaxElements = maxElements;

	std::vector<Ogre::Vector3*> * mapPoints = calcCurve(mapConfiguration);

	//std::vector<Ogre::Vector3*> * mapPoints = CurveGenerator::generateCurve(&mapBPoints, resolution);

	//MapElements3 = {
	//	BaseElements = {
	//		numBases = 1,
	//		element1 = {mesh="Meteor1.mesh", controlLogic="DoNothingControlLogic",collisionGroup=5, weight=3000000000.0, boundingBox=1.0, isStatic=false, isKinematic=true, actorDesc="MapElement"}
	//	},
	//	SpecElements = {
	//		numSpecs = 2,
	//		element1 = {mesh="OrangeRocket01.mesh", controlLogic="DoNothingControlLogic",collisionGroup=5, weight=3000000000.0, boundingBox=1.0, isStatic=false, isKinematic=true, actorDesc="MapElement"},
	//		element2 = {mesh="Satelit02.mesh", controlLogic="DoNothingControlLogic",collisionGroup=5, weight=3000000000.0, boundingBox=1.0, isStatic=false, isKinematic=true, actorDesc="MapElement"}
	//	}
	//}

	luabind::object luaStartPos = luabind::object_cast<luabind::object>(mapConfiguration["startPosition"]);
	float startx = luabind::object_cast<float>(luaStartPos["x"]);
	float starty = luabind::object_cast<float>(luaStartPos["y"]);
	float startz = luabind::object_cast<float>(luaStartPos["z"]);
	Ogre::Vector3 startPos = Ogre::Vector3(startx,starty,startz);


	luabind::object elementTypes = luabind::object_cast<luabind::object>(mapConfiguration["elementTypes"]);

	// BaseElements
	luabind::object baseElements = luabind::object_cast<luabind::object>(elementTypes["BaseElements"]);

	int numberOfBaseElements = luabind::object_cast<int>(baseElements["numBases"]);

	std::vector<luabind::object> baseE;
	for(int i = 1; i <= numberOfBaseElements; i++)
	{
		luabind::object currentBaseElement = luabind::object_cast<luabind::object>(baseElements["element" + Ogre::StringConverter::toString(i)]);
		baseE.push_back(currentBaseElement);
	}

	// SpecElements
	luabind::object specElements = luabind::object_cast<luabind::object>(elementTypes["SpecElements"]);

	int numberOfSpecElements = luabind::object_cast<int>(specElements["numSpecs"]);

	std::vector<luabind::object> specE;
	for(int i = 1; i <= numberOfSpecElements; i++)
	{
		luabind::object currentSpecElement = luabind::object_cast<luabind::object>(specElements["element" + Ogre::StringConverter::toString(i)]);
		specE.push_back(currentSpecElement);
	}


	// Collectibles
	luabind::object collectibles = luabind::object_cast<luabind::object>(elementTypes["Collectibles"]);

	int numberOfCollectibles = luabind::object_cast<int>(collectibles["numCollectibles"]);

	std::vector<luabind::object> collectbilesVector;
	for(int i = 1; i <= numberOfCollectibles; i++)
	{
		luabind::object currentCollectible = luabind::object_cast<luabind::object>(collectibles["element" + Ogre::StringConverter::toString(i)]);
		collectbilesVector.push_back(currentCollectible);
	}


	

	Ogre::SceneNode* mapNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
	Ogre::SceneNode* mapControlNode = controlSceneManager->getRootSceneNode()->createChildSceneNode();

	srand(time(0)); // Initialize random number generator.
	// (rand() % MAX) + Start

	// (2.0/resolution) -> start from 2nd basepoint ([2.0/resolution]th map point)
	for(int i = (2.0/resolution), elementCTR = 0; i < mapPoints->size(); i++)
	{
		//"media/audio/music/titlemusic.wav"
		//palyAudioFromFile(Ogre::String filePath, bool looping, float pitch = 1.0, Ogre::Vector3 position = Ogre::Vector3::ZERO)

		// Generate meteors
		while ((rand() % 100 < percent) && (countToMaxElements-- > 0))
		{
			luabind::object selectedElement =  baseE[rand() % (numberOfBaseElements-1)];

			luabind::object luaScale = luabind::object_cast<luabind::object>(selectedElement["scale"]);
			float sx = luabind::object_cast<float>(luaScale["x"]);
			float sy = luabind::object_cast<float>(luaScale["y"]);
			float sz = luabind::object_cast<float>(luaScale["z"]);

			luabind::object func = luabind::object_cast<luabind::object>(selectedElement["func"]);

			Ogre::Vector3 pos = *mapPoints->at(i) + Ogre::Vector3((rand() % 300)-150, (rand() % 300)-150, (rand() % 300)-150);
			Ogre::Vector3 scale = Ogre::Vector3(sx*((float)(rand() % 150 + 50)/100.0), sy*((float)(rand() % 150 + 50)/100.0),sz*((float)(rand() % 150 + 50)/100.0));

			if((startPos-pos).length()>100)
			{


				Ogre::SceneNode* elementNode = mapNode->createChildSceneNode(pos);
				elementNode->scale(scale);
				elementNode->setOrientation(1.0, pos.y, pos.z, pos.x);
				Ogre::SceneNode* elementControlNode = mapControlNode->createChildSceneNode(pos);
				elementControlNode->scale(scale);
				elementControlNode->setOrientation(1.0, pos.y, pos.z, pos.x);

				addPhysicsEntity("baseElement" + Ogre::StringConverter::toString(elementCTR++), elementNode, elementControlNode, selectedElement, func);
			}
		}

		// 0/1 SpaceJunk
		if (rand() % 100 < percent/2)
		{
			luabind::object selectedElement =  specE[rand() % (numberOfSpecElements-1)];

			luabind::object luaScale = luabind::object_cast<luabind::object>(selectedElement["scale"]);
			float sx = luabind::object_cast<float>(luaScale["x"]);
			float sy = luabind::object_cast<float>(luaScale["y"]);
			float sz = luabind::object_cast<float>(luaScale["z"]);

			luabind::object func = luabind::object_cast<luabind::object>(selectedElement["func"]);

			Ogre::Vector3 pos = *mapPoints->at(i) + Ogre::Vector3((rand() % 300)-150, (rand() % 300)-150, (rand() % 300)-150);
			Ogre::Vector3 scale = Ogre::Vector3(sx*((float)(rand() % 150 + 50)/100.0), sy*((float)(rand() % 150 + 50)/100.0),sz*((float)(rand() % 150 + 50)/100.0));


			if((startPos-pos).length()>100)
			{


				Ogre::SceneNode* elementNode = mapNode->createChildSceneNode(pos);
				elementNode->scale(scale);
				elementNode->setOrientation(1.0, pos.y, pos.z, pos.x);
				Ogre::SceneNode* elementControlNode = mapControlNode->createChildSceneNode(pos);
				elementControlNode->scale(scale);
				elementControlNode->setOrientation(1.0, pos.y, pos.z, pos.x);

				addPhysicsEntity("specElement" + Ogre::StringConverter::toString(i), elementNode, elementControlNode,selectedElement , func);
			}

		}


		if (rand() % 100 < percent/4)
		{
			luabind::object selectedElement;

			if(numberOfCollectibles==1)
			{
				selectedElement =  collectbilesVector[0];
			}
			else
			{
				selectedElement =  collectbilesVector[rand() % (numberOfCollectibles-1)];
			}
			

			luabind::object luaScale = luabind::object_cast<luabind::object>(selectedElement["scale"]);
			float sx = luabind::object_cast<float>(luaScale["x"]);
			float sy = luabind::object_cast<float>(luaScale["y"]);
			float sz = luabind::object_cast<float>(luaScale["z"]);

			luabind::object func = luabind::object_cast<luabind::object>(selectedElement["func"]);

			Ogre::Vector3 pos = *mapPoints->at(i) + Ogre::Vector3((rand() % 100)-50, (rand() % 100)-50, (rand() % 100)-50);
			Ogre::Vector3 scale = Ogre::Vector3(sx, sy,sz);



			Ogre::SceneNode* elementNode = mapNode->createChildSceneNode(pos);
			elementNode->scale(scale);
			elementNode->setOrientation(1.0, 0, 0,0);
			Ogre::SceneNode* elementControlNode = mapControlNode->createChildSceneNode(pos);
			elementControlNode->scale(scale);
			elementControlNode->setOrientation(1.0, pos.y, pos.z, pos.x);

			addPhysicsEntity("collectible" + Ogre::StringConverter::toString(i), elementNode, elementControlNode,selectedElement , func);

		}



		countToMaxElements = maxElements;
	}


	delete mapPoints;

}

//Ide mehetnek a menu hatterebe levo dolgok
void Game::createMenu(Ogre::String script)
{
	if(mGameOFF==true)
	{
		destroyGame();
	}


	mGameOFF = false;

	runScript(script);


	//mSceneMgr->getCamera("mainCam")->setFarClipDistance(0.5);
	mWindow->getViewport(0)->setCamera(mSceneMgr->getCamera("mainCam"));

	new PSysFromScript(Ogre::Vector3(0,-20,-200), mSceneMgr, "bumm", &pSystems);

	mSceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_MODULATIVE);
	mSceneMgr->setShadowColour(Ogre::ColourValue(0.5,0.5,0.5));

	//CREATING THE SKY
	Ogre::Plane skyPlane;
	skyPlane.d = 1000;
	skyPlane.normal = Ogre::Vector3::NEGATIVE_UNIT_Y;
	//mSceneMgr->setSkyPlane(true, skyPlane, "SkyMaterial/SpaceSkyPlane", 1500, 50,true, 1.5f, 150,150);

	//mSceneMgr->setSkyBox(true, "SkyMaterial/SpaceSkyPlane");

	// No PhysicsEntities at start
	//mNumEntitiesInstanced = 0;
	// MoveSpeed of the bullet simulation
	//mMoveSpeed = 50;

	// Set ambient light
	mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5,1));

	// pointLight
	Ogre::Light* pointLight = mSceneMgr->createLight("pointLight");
	pointLight->setType(Ogre::Light::LT_POINT);
	pointLight->setPosition(Ogre::Vector3(200, 0, 0));

	pointLight->setDiffuseColour(0.2, 0.2, 0.2);
	pointLight->setSpecularColour(0.2, 0.2, 0.2);

	// Create a light
	light = mSceneMgr->createLight("MainLight");
	light->setType(Ogre::Light::LT_POINT);
	light->setAttenuation(1000.0,0.0,0.0,1.0);
	light->setPowerScale(1000);
	light->setCastShadows(true);
	light->setPosition(0,0, -40);

	Ogre::Light* pDirLight = mSceneMgr->createLight();
	pDirLight->setDirection(Ogre::Vector3(0, -1, 0));
	pDirLight->setType(Ogre::Light::LT_DIRECTIONAL);


	//mSceneMgr->setFog(Ogre::FOG_LINEAR, Ogre::ColourValue(0.5,0.5,0.5), 0.0, 10, 2000);

	//mRaySceneQuery = mSceneMgr->createRayQuery(Ogre::Ray());


}



void Game::destroyMenu()
{
	rCameraUsed = false;




	//mPhysicsSDK->releaseScene(*mNxScene);
	mPhysicsSubsystem->destroyPhysicsScene();
	mPhysicsScene = mPhysicsSubsystem->createPhysicsScene();

	//initNxScene();


	//mNxScene->setUserContactReport(&contactReport);


	mSceneMgr->destroyAllEntities();
	mSceneMgr->destroyAllCameras();
	mSceneMgr->destroyAllParticleSystems();
	mSceneMgr->destroyAllLights();

	mSceneMgr->setSkyBox(false, "");
	mSceneMgr->setSkyDome(false, "");
	mSceneMgr->setSkyPlane(false, Ogre::Plane(), "");

	gameAudio->stopAllAudioSource();

	delete rCamera;



	Ogre::SceneManager::MovableObjectIterator i = controlSceneManager->getMovableObjectIterator("ManualObject");

	while( i.hasMoreElements())
	{

		EntityControl * cur_entity = (EntityControl*)i.getNext();

		controlSceneManager->destroyManualObject(cur_entity);
	}

	controlSceneManager->clearScene();

	StackAllocatorManager::getSingleton().resetLevelScopeAllocators();


}

//Luabol hivjuk ha lenyomodik a gomb
void Game::startGame(Ogre::String script)
{


	mGameScript = script;

	mGameON = true;


}

void Game::createGame(Ogre::String script)
{
	destroyMenu();

	//mRaySceneQuery = mSceneMgr->createRayQuery(Ogre::Ray());

	runScript(script);

	mWindow->getViewport(0)->setCamera(mSceneMgr->getCamera("mainCam"));

	mGameON = false;

}

void Game::finishGame(Ogre::String script)
{


	mMenuScript = script;

	mGameOFF = true;


}


void Game::destroyGame()
{
	rCameraUsed = false;

	Ogre::SceneManager::MovableObjectIterator i = controlSceneManager->getMovableObjectIterator("ManualObject");


	//mPhysicsSDK->releaseScene(*mNxScene);
	mPhysicsSubsystem->destroyPhysicsScene();
	mPhysicsScene = mPhysicsSubsystem->createPhysicsScene();

	//initNxScene();
	//mNxScene->setUserContactReport(&contactReport);


	mSceneMgr->destroyAllEntities();
	mSceneMgr->destroyAllCameras();
	mSceneMgr->destroyAllParticleSystems();
	mSceneMgr->destroyAllLights();

	mSceneMgr->setSkyBox(false, "");
	mSceneMgr->setSkyDome(false, "");
	mSceneMgr->setSkyPlane(false, Ogre::Plane(), "");

	gameAudio->stopAllAudioSource();

	delete rCamera;



	while( i.hasMoreElements())
	{

		EntityControl * cur_entity = (EntityControl*)i.getNext();
		//controlSceneManager->destroyManualObject((Ogre::ManualObject*)cur_entity);
		//cur_entity->clear();
		controlSceneManager->destroyManualObject(cur_entity);
	}

	controlSceneManager->clearScene();

	//controlSceneManager = mRoot->createSceneManager(Ogre::ST_GENERIC,"controlSceneManager");

	//mainHUD->hide();

	StackAllocatorManager::getSingleton().resetLevelScopeAllocators();

	//mGameOFF = true;

}


void Game::processUnbufferedKeyInput(const Ogre::FrameEvent& evt)
{ 		
	//	
	//
	//	if(mKeyboard->isKeyDown(OIS::KC_U))
	//	{
	//		if(mKeyboard->isKeyDown(OIS::KC_H))
	//			move->processKeyInput(OIS::KC_U*100+OIS::KC_H);
	//		else
	//			move->processKeyInput(OIS::KC_U);
	//	}
	//
	//	if(mKeyboard->isKeyDown(OIS::KC_I))
	//	{
	//		if(mKeyboard->isKeyDown(OIS::KC_H))
	//			move->processKeyInput(OIS::KC_I*100+OIS::KC_H);
	//		else
	//		move->processKeyInput(OIS::KC_I);
	//	}
	//
	//	if(mKeyboard->isKeyDown(OIS::KC_O))
	//	{
	//		if(mKeyboard->isKeyDown(OIS::KC_H))
	//			move->processKeyInput(OIS::KC_O*100+OIS::KC_H);
	//		else
	//		move->processKeyInput(OIS::KC_O);
	//	}
	//
	//	if(mKeyboard->isKeyDown(OIS::KC_J))
	//	{
	//		if(mKeyboard->isKeyDown(OIS::KC_H))
	//			move->processKeyInput(OIS::KC_J*100+OIS::KC_H);
	//		else
	//		move->processKeyInput(OIS::KC_J);
	//	}
	//
	//	if(mKeyboard->isKeyDown(OIS::KC_K))
	//	{
	//		if(mKeyboard->isKeyDown(OIS::KC_H))
	//			move->processKeyInput(OIS::KC_K*100+OIS::KC_H);
	//		else
	//		move->processKeyInput(OIS::KC_K);
	//	}
	//
	//	if(mKeyboard->isKeyDown(OIS::KC_L))
	//	{
	//		if(mKeyboard->isKeyDown(OIS::KC_H))
	//			move->processKeyInput(OIS::KC_L*100+OIS::KC_H);
	//		else
	//		move->processKeyInput(OIS::KC_L);
	//	}
	//
	//	if(mKeyboard->isKeyDown(OIS::KC_M))
	//	{
	//		if(mKeyboard->isKeyDown(OIS::KC_H))
	//			move->processKeyInput(OIS::KC_M*100+OIS::KC_H);
	//		else
	//		move->processKeyInput(OIS::KC_M);
	//	}
	//
	//	if(mKeyboard->isKeyDown(OIS::KC_N))
	//	{
	//		if(mKeyboard->isKeyDown(OIS::KC_H))
	//			move->processKeyInput(OIS::KC_M*100+OIS::KC_H);
	//		else
	//		move->processKeyInput(OIS::KC_N);
	//	}
	//	if (mKeyboard->isKeyDown(OIS::KC_X))
	//	{
	//		if ( Ogre::CompositorManager::getSingleton().getCompositorChain(mWindow->getViewport(0))->getCompositor("Negative")->getEnabled() )
	//			Ogre::CompositorManager::getSingleton().setCompositorEnabled(mWindow->getViewport(0), "Negative", false);
	//		else
	//			Ogre::CompositorManager::getSingleton().setCompositorEnabled(mWindow->getViewport(0), "Negative", true);
	//	}
	//	if (mKeyboard->isKeyDown(OIS::KC_Y))
	//	{
	//		if ( Ogre::CompositorManager::getSingleton().getCompositorChain(mWindow->getViewport(0))->getCompositor("Monochrome")->getEnabled() )
	//			Ogre::CompositorManager::getSingleton().setCompositorEnabled(mWindow->getViewport(0), "Monochrome", false);
	//		else
	//			Ogre::CompositorManager::getSingleton().setCompositorEnabled(mWindow->getViewport(0), "Monochrome", true);
	//	}
	//	if (mKeyboard->isKeyDown(OIS::KC_SPACE))
	//	{
	//		mWindow->getViewport(0)->setClearEveryFrame(true, Ogre::FBT_DEPTH);
	//		mRoot->getSingleton().getRenderSystem()->clearFrameBuffer(Ogre::FBT_COLOUR, Ogre::ColourValue::Black);
	//		Ogre::CompositorManager::getSingleton().setCompositorEnabled(mWindow->getViewport(0), "MotionBlur", true);
	//	}
	//
}

void Game::createFrameListener(void)
{





	//mRoot->addFrameListener(this);
}
bool Game::frameStarted(const Ogre::FrameEvent& evt)
{


	//mWorld->stepSimulation(evt.timeSinceLastFrame);	// update Bullet Physics animation

	return true;
}

bool Game::frameEnded(const Ogre::FrameEvent& evt)
{

	//CommonFunctions::DebugOutputWrite("Time since last event: %f , time since last frame: %f\n", evt.timeSinceLastEvent, evt.timeSinceLastFrame);

	//mWorld->stepSimulation(evt.timeSinceLastFrame);	// update Bullet Physics animation

	return true;
}


bool Game::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
	bool ret = true;

	/*if (!inited)
	return true;*/

	/*mNxScene->simulate(evt.timeSinceLastFrame);
	mNxScene->flushStream();*/
	mPhysicsScene->stepSimulation(evt.timeSinceLastFrame);



	control(evt.timeSinceLastEvent);

	//showing the camera image of the Eye
	//copyCameraImageToTexture(camImage);

	processUnbufferedKeyInput(evt);

	if(rCameraUsed)
		rCamera->Step(evt.timeSinceLastEvent);

	/*Move::Quaternion orientation = move->getOrientation(0);
	moveTest->getParentSceneNode()->setOrientation(orientation.w,orientation.x,orientation.y,orientation.z);*/

	int r = rand()%100;

	if(1 )
	{
		if(!pSystems.empty())
		{
			Ogre::ParticleSystem * pSys = pSystems.front();
			if(pSys->getNumParticles() ==0 )
			{

				pSystemZeroCount++;

				if(pSystemZeroCount >= 5)
				{
					pSystems.pop_front();
					mSceneMgr->destroyParticleSystem(pSys);
					pSystemZeroCount = 0;
				}
			}
			else
			{
				pSystems.pop_front();
				pSystems.push_back(pSys);
				pSystemZeroCount = 0;
			}

		}
	}


	//CEGUI::System::getSingleton().injectTimePulse(evt.timeSinceLastFrame);

	/*if(mGameOFF)
	{
	destroyGame();
	createMenu("");
	}*/

	if(mGameON)
	{
		createGame(mGameScript);
	}

	if(mGameOFF)
	{
		createMenu(mMenuScript);
	}






	return (ret && (!mShutDown));

}
//-------------------------------------------------------------------------------------
bool Game::configure()
{
	OGRE_NEW_T(StackAllocatorManager, Ogre::MEMCATEGORY_GENERAL);

	mSceneMgr = mRoot->createSceneManager(Ogre::ST_GENERIC);
	controlSceneManager = mRoot->createSceneManager(Ogre::ST_GENERIC,"controlSceneManager");

	/*mOverlaySystem = new Ogre::OverlaySystem();
	mSceneMgr->addRenderQueueListener(mOverlaySystem);*/


	//mDebugOverlay = Ogre::OverlayManager::getSingleton().getByName("Core/DebugOverlay");


	if (!initMove())
		return false;
	else
		//Aftter we got the move controller, we can bind it to the ControlStatus
		initControlStatus();

	// Initializing PhysX
	initPhysX();

	//TODO: kiszedtem, ha kell, visszarakjuk
	//move->PassWindowParam(width,height);
	setupLuabindings();


	return true;
}
//-------------------------------------------------------------------------------------
bool Game::initMove()
{
	/*Ogre::ConfigFile cf; 
	cf.load("settings.cfg");
	Ogre::String emu_enabled = cf.getSetting("enabled","Emulator");*/

	/*if (emu_enabled.compare("true")==0)
	{
	move = Move::createEmulator();						
	}
	else
	move = Move::createRealDevice();*/

	//move = Move::createDevice();

	/*if (move->initMoves()<1)
	{
	return false;
	}
	move->initCamera();*/


	return true;
}

void Game::initControlStatus()
{
	//controlStatus.bindController(move);
}
//-------------------------------------------------------------------------------------
// You may remove the comment, if you want to test with PS Move only

//bool Game::keyPressed( const OIS::KeyEvent &arg )
//{
//bool ret = BaseApplication::keyPressed(arg);
//
////if ((arg.key == OIS::KC_J) || (arg.key == OIS::KC_K) || (arg.key == OIS::KC_L) || 
////(arg.key == OIS::KC_I)|| (arg.key == OIS::KC_O) || (arg.key == OIS::KC_U)  ||
////(arg.key == OIS::KC_N)|| (arg.key == OIS::KC_M))
////move->PassKeyPressed(arg);
//
//	if(arg.key ==OIS::KC_TAB)
//	{
//		currentScheme = (++currentScheme)%schemecount;
//		mWindow->getViewport(0)->setMaterialScheme(qualitySchemes[currentScheme]);
//
//	}
//
//return true;
//}

//-------------------------------------------------------------------------------------
// You may remove the comment, if you want to test with PS Move only
/*
bool Game::keyReleased( const OIS::KeyEvent &arg )
{

if ((arg.key == OIS::KC_J) || (arg.key == OIS::KC_K) || (arg.key == OIS::KC_L) || (arg.key == OIS::KC_I)|| (arg.key == OIS::KC_O) || (arg.key == OIS::KC_U))
move->PassKeyReleased(arg);

return true;
}
*/

void Game::initPhysX()
{
	//inited = false;

	mPhysicsSubsystem = (UltimatePhysicsSubsystem*)  UltimateSubsystemRegistry::getSingletonPtr()->getSubsystem(PHYSICS_SUBSYSTEM);
	if(!mPhysicsSubsystem)
		mPhysicsSubsystem = new UltimatePhysicsSubsystemMock();
	mPhysicsSubsystem->initPhysics();
	mPhysicsScene = mPhysicsSubsystem->createPhysicsScene();

	mPhysicsScene->addContactListener(&contactReport);
	contactReport.setGameAudio(gameAudio);

	//mPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION);
	//if (!mPhysicsSDK)  return;

	//mPhysicsSDK->getFoundationSDK().getRemoteDebugger()->connect("localhost", 5425);

	//mPhysicsSDK->setParameter(NX_SKIN_WIDTH, 0.01);
	//
	//	mNxSceneDesc.simType = NX_SIMULATION_HW;
	////mNxSceneDesc.gravity = NxVec3(0,-90.8f,0);
	//mNxSceneDesc.gravity = NxVec3(0,0,0);
	////sceneDesc.groundPlane = true;

	//
	//if(!initNxScene())
	//	return;


	//inited = true;
}


bool Game::initNxScene()
{
	//mNxScene = mPhysicsSDK->createScene(mNxSceneDesc);	
	//if(!mNxScene)
	//{ 
	//	mNxSceneDesc.simType = NX_SIMULATION_SW; 
	//	mNxScene = mPhysicsSDK->createScene(mNxSceneDesc); 
	//	if(!mNxScene) return false;
	//}

	//
	//mNxScene->setActorGroupPairFlags(2,3, NX_NOTIFY_ON_START_TOUCH);
	//mNxScene->setActorGroupPairFlags(1,3, NX_NOTIFY_ON_START_TOUCH);
	//mNxScene->setActorGroupPairFlags(3,1, NX_NOTIFY_ON_START_TOUCH);
	//mNxScene->setActorGroupPairFlags(1,6, NX_NOTIFY_ON_START_TOUCH);
	//mNxScene->setActorGroupPairFlags(6,1, NX_NOTIFY_ON_START_TOUCH);
	//mNxScene->setActorGroupPairFlags(5,3, NX_NOTIFY_ON_START_TOUCH);
	//mNxScene->setActorGroupPairFlags(3,5, NX_NOTIFY_ON_START_TOUCH);

	//// Create the default material
	//NxMaterial* defaultMaterial = mNxScene->getMaterialFromIndex(0); 
	//defaultMaterial->setRestitution(0.5);
	//defaultMaterial->setStaticFriction(0.5);
	//defaultMaterial->setDynamicFriction(0.5);

	return true;
}
//-------------------------------------------------------------------------------------
void Game::setScriptFileReader(CustomScriptFileReader * reader)
{
	mScriptFileReader = reader;
	customReaderUsed = true;

}
//-------------------------------------------------------------------------------------
void  Game::setGameOverHandler(GameOverHandler *gameOverHandler)
{
	mGameOverHandler = gameOverHandler;
	gameOverHandlerUsed = true;
}



//-------------------------------------------------------------------------------------
//bool Game::mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
//{
//	if(id ==OIS::MB_Right)
//	{
//		currentScheme = (++currentScheme)%schemecount;
//		mWindow->getViewport(0)->setMaterialScheme(qualitySchemes[currentScheme]);
//
//	}
//
//	//CEGUI::System::getSingleton().injectMouseButtonDown(convertButton(id));
//
//	return true;
//}
//
////-------------------------------------------------------------------------------------
//bool Game::mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
//{
//	
//
//	//CEGUI::System::getSingleton().injectMouseButtonUp(convertButton(id));
//
//	return true;
//}
//
////-------------------------------------------------------------------------------------
//
//
//bool Game::mouseMoved( const OIS::MouseEvent &arg )
//{
//	
//	//move->passMouseMoved(arg.state.X.rel,arg.state.Y.rel,arg.state.Z.rel);
//
//
//	//CEGUI::System::getSingleton().injectMouseMove(arg.state.X.rel, arg.state.Y.rel);
//
//	return true;
//}
//-------------------------------------------------------------------------------------

void Game::control(Ogre::Real dt)
{
	//controlStatus.UpdateStatus(mKeyboard);

	controlStatus.updateStatus(mInputSubsystem->handleInput());
	isAnyoneWaiting = false;
	nodeControl(ControlContext(controlStatus,gameStatus, dt), controlSceneManager->getRootSceneNode());
	if(isAnyoneWaiting)
	{
		gameStatus = ControlContext::WAITING;
	}else
	{
		gameStatus = ControlContext::PLAYING;
	}

	mInputSubsystem->clearInput();
}


void Game::nodeControl(const ControlContext& context, Ogre::SceneNode* node)
{
	EntityControl* currentEntity;
	std::string name = node->getName();



	Ogre::SceneNode::ObjectIterator entityIterator = node->getAttachedObjectIterator();
	while(entityIterator.hasMoreElements())
	{

		currentEntity = (EntityControl*)entityIterator.getNext();

		// Control
		std::vector<Controller*> *controllers = currentEntity->getControllers();


		if(currentEntity->isReadyToDie())
		{
			/*NxActor *actor = currentEntity->getPhysicsActor()->getNxActor();
			actor->userData=NULL;
			mNxScene->releaseActor(*actor);

			Ogre::Entity * modelEntity = currentEntity->getModelActor();


			modelEntity->detachFromParent();

			mSceneMgr->destroyEntity(currentEntity->getModelActor());*/

			/*
			OGRE_DELETE currentEntity;*/

			currentEntity->deleteBodies();

			currentEntity->detachFromParent();

			controlSceneManager->destroyManualObject(currentEntity);



			break;

		}
		if(currentEntity->isWaiting())
		{
			isAnyoneWaiting = true;
		}


		if(currentEntity->isGameOver())
		{
			//mSceneMgr->getEntity("GroundEntity")->detachFromParent();
			mWindow->getViewport(0)->setCamera(rCamera->getCamera());
			rCameraUsed=true;
			//mGameOFF=true;

			gameStatus=ControlContext::GAMEOVER;

			if(gameOverHandlerUsed)
			{

				std::map<std::string,int> resultMap;

				for(int i=0; i< requiredGameResultList.size(); i++)
				{

					std::string resultName = requiredGameResultList[i][0];
					std::string entityName = requiredGameResultList[i][1];
					std::string parameterName = requiredGameResultList[i][2];

					EntityControl * entity = (EntityControl*) controlSceneManager->getManualObject(entityName);

					resultMap[resultName] = ((IntEntityParameter*) entity->getParameter(parameterName))->getIntValue();
				}

				mGameOverHandler->handleGameOver(&resultMap);
			}


		}


		for(int i=0; i<controllers->size(); i++)
		{
			Controller * controller = controllers->at(i);




			bool nextController = currentEntity->control(controller,context);





			// If TargetController, then launch projectiles

			while(controller->isSpawningNeeded())
			{

				TargetController::Projectile newProjectile = controller->getNextSpawnItem();


				// Get the parent scene node for model and phy
				Ogre::SceneNode* node; 

				if(currentEntity->getMasterBody()->getParentNode()->getParentSceneNode())
				{
					node = currentEntity->getMasterBody()->getParentNode()->getParentSceneNode()->createChildSceneNode();
				}
				else
				{
					node = currentEntity->getMasterBody()->getParentNode()->createChildSceneNode();
				}

				node->setPosition(
					currentEntity->getMasterBody()->getParentNode()->getPosition()
					+ newProjectile.position);


				// Get the parent scene node for control
				Ogre::SceneNode* controlNode =
					currentEntity->getParentSceneNode()->getParentSceneNode()->createChildSceneNode();


				// SHOOOOOOOOO0000000o0o0oo0o0!!!44!!!44!4!44!four!!4!
				addProjectile(
					newProjectile, node, controlNode, "DoNothingControlLogic");
			}

			if(!nextController)
			{
				break;
			}

		}


	}

	Ogre::Node::ChildNodeIterator iterator = node->getChildIterator();
	while(iterator.hasMoreElements())
	{
		nodeControl(context, (Ogre::SceneNode*)iterator.getNext());
	}

}

//void Game::copyCameraImageToTexture(Ogre::TexturePtr texture)
//{
//	int eyeX, eyeY;
//	move->getEyeDimensions(eyeX,eyeY);
//
//	PBYTE eyeBuffer=move->getEyeBuffer();
//	if (eyeBuffer)
//	{
//		Ogre::HardwarePixelBufferSharedPtr buffer = texture->getBuffer(0,0);
//		buffer->lock(Ogre::HardwareBuffer::HBL_DISCARD);
//		const Ogre::PixelBox &pb = buffer->getCurrentLock();
//		PBYTE data = static_cast<PBYTE>(pb.data);
//		memcpy(data,eyeBuffer,eyeX*eyeY*4);
//
//		for (size_t j = 0; j < eyeX; j++)
//			for(size_t i = 0; i < eyeY; i++)
//			{
//				*data++; // B
//				*data++; // G
//				*data++; // R
//				*data++ = 255; // A
//			}
//			buffer->unlock();
//	}
//}

//-------------------------------------------------------------------------------------
bool Game::quit()
{
	mShutDown = true;
	return true;
}





//CEGUI::MouseButton Game::convertButton(OIS::MouseButtonID buttonID)
//{
//    switch (buttonID)
//    {
//    case OIS::MB_Left:
//        return CEGUI::LeftButton;
// 
//    case OIS::MB_Right:
//        return CEGUI::RightButton;
// 
//    case OIS::MB_Middle:
//        return CEGUI::MiddleButton;
// 
//    default:
//        return CEGUI::LeftButton;
//    }
//}













//-------------------------------------------------------------------------------------
void Game::setupLuabindings()
{
	using namespace luabind;
	// Create a new lua state
	LuaState = lua_open();
	// Connect LuaBind to this lua state
	luabind::open(LuaState);
	luaL_openlibs(LuaState);
	// Export our class with LuaBind
	luabind::module(LuaState) [
		luabind::class_<Ogre::SceneNode>("SceneNode"),
			luabind::class_<BodyRailControlLogic>("BodyRailControlLogic"),
			luabind::class_<TargetControlLogic>("TargetControlLogic"),
			luabind::class_<EntityControl>("EntityControl"),
			luabind::class_<EntityBody>("EntityBody"),
			luabind::class_<OgreEntityBody>("OgreEntityBody"),
			luabind::class_<PhysicsEntityBody>("PhysicsEntityBody"),
			luabind::class_<ParticleEntityBody>("ParticleEntityBody"),
			luabind::class_<NodeEntityBody>("NodeEntityBody"),
			luabind::class_<Trigger>("Trigger"),
			luabind::class_<UltimatePhysicsActorDesc>("ActorDesc"),
			luabind::class_<AIControlLogic>("AIControlOgic"),
			luabind::class_<AIGoal>("AIGoal"),
			luabind::class_<VectorEntityParameter>("VectorEntityParameter"),
			luabind::class_<PlayerProjectileControlLogic>("PlayerProjectileControlLogic"),
			luabind::class_<Game>("Game")
			.def("setAmbient", &Game::SetAmbientLightColor)
			.def("createNode", &Game::createSceneNode)
			.def("addNode", &Game::addSceneNode)
			.def("StaticEntity", &Game::addStaticEntity)
			.def("PhysicsEntity", &Game::addPhysicsEntity)
			.def("addHUD", &Game::addHUD)
			.def("setGravity", &Game::setGravity)
			.def("createBodyRailControlLogic",&Game::addBodyRailControlLogic)
			.def("createTargetControlLogic",&Game::addTargetControlLogic)
			.def("createMap",&Game::createMap)
			.def("Target",&Game::addTarget)
			.def("ProjectileTarget", &Game::addProjectileTarget)
			.def("PhysicsTerrain", &Game::addPhysicsTerrain)
			.def("setCamera", &Game::setCamera)
			.def("Launcher", &Game::addLauncher)
			.def("setRoundCamera", &Game::SetRoundCamera)
			.def("createCamera", &Game::createCamera)
			.def("createActorDesc",&Game::createActorDesc)
			.def("BoxShape",&Game::addBoxShapeDesc)
			.def("bindFunctionGUI",&Game::bindFunctionGUI)
			.def("loadLayoutGUI",&Game::loadLayoutGUI)
			.def("setWindowVisible",&Game::setWindowVisible)
			.def("quit",&Game::quit)
			.def("startGame",&Game::startGame)
			.def("finishGame",&Game::finishGame)
			.def("createMenu",&Game::createMenu)
			.def("setCursorVisible",&Game::setCursorVisible)
			.def("Entity", &Game::addEntity)
			.def("PhysicsBody", &Game::addPhysicsBody)
			.def("OgreBody", &Game::addOgreBody)
			.def("ParticleSystemBody", &Game::addParticleSystemBody)
			.def("NodeBody", &Game::addNodeBody)
			.def("setMasterBody", &Game::setMasterBody)
			.def("addController", &Game::addController)
			.def("setEntityStatus", &Game::setEntityStatus)
			.def("addResultMapEntry", &Game::addGameResultEntry)
			.def("bindKey", &Game::bindKey)
			.def("bindButtonKey", &Game::bindButtonKey)
			.def("createPlayerProjectileControlLogic",&Game::addPlayerProjectileControlLogic)
			.def("bindPojectileToKey",&Game::bindPojectileToKey)
			.def("setMaxProjectileCount",&Game::setMaxProjectileCount)
			//----------------------Audio---------------------------------
			.def("setAudioListenerPose", &Game::setAudioListenerPose)
			.def("createAudioWithName", &Game::createAudioWithName)
			.def("setAudioWithName", &Game::setAudioWithName)
			.def("playAudioByName", &Game::playAudioByName)
			.def("playAudioFromFile", &Game::playAudioFromFile)
			.def("stopAudioByName", &Game::stopAudioByName)
			.def("stopAllAudioSource", &Game::stopAllAudioSource)
			.def("deleteAllAudioSource", &Game::deleteAllAudioSource)
			//---------------------Trigger--------------------------------
			.def("addTrigger",&Game::addTrigger)
			.def("DamageAction",&Game::createDamageAction)
			.def("PositionReq",&Game::createPositionReq)
			.def("CustomScriptAction",&Game::createCustomScriptAction)
			.def("PSysAction", &Game::createPSysAction)
			.def("GameOverAction", &Game::createGameOverAction)
			.def("KilledReq", &Game::createKilledReq)
			.def("ExplodeAction",&Game::createExplodeAction)
			.def("NegateReq",&Game::createNegateReq)
			.def("FreeRayReq",&Game::createFreeRayReq)
			.def("KillAction",&Game::createKillAction)
			.def("FreeMoveAction",&Game::createFreeMoveAction)
			.def("OnRailMoveAction",&Game::createOnRailMoveAction)
			//---------------------AI-----------------------------------
			.def("createAIControlLogic",&Game::createAIControlLogic)
			.def("addAIGoal",&Game::addAIGoal)
			.def("addAIGoalRecord",&Game::addAIGoalRecord)
			.def("addTriggerToGoal",&Game::addTriggerToGoal)
			.def("createVectorEntityParameter",&Game::createVectorEntityParameter)
			//--------------------Network-------------------------------
			.def("createNetworkContrologic",&Game::createNetworkContrologic)
			.def("setTargetServer",&Game::setTargetServer)
			.def("createServer",&Game::createServer)
			.def("startNetworkSession",&Game::startNetworkSession)
			.def("stopNetworkSession",&Game::stopNetworkSession)

	];
	// Now use this class in a lua script
	int s = luaL_dostring(LuaState, "game = nil; function setGame(e) game = e end"); 
	if(s != 0)  
	{  
		std::string errs = lua_tostring(LuaState, -1); 
		/* MessageBoxA( NULL, errs.c_str(), "Lua error!", MB_OK);*/ 
		Ogre::LogManager::getSingleton().logMessage(Ogre::LML_CRITICAL,errs.c_str());
	}
	call_function<Game*>(LuaState, "setGame", this);
}
//-------------------------------------------------------------------------------------
void Game::runScript(std::string luaFile)
{	
	int s = 1;
	if(customReaderUsed)
	{
		Ogre::LogManager::getSingletonPtr()->logMessage(Ogre::LML_NORMAL,Ogre::String("Opening lua file with custom script reader: ")+luaFile);
		s = luaL_dostring(LuaState, mScriptFileReader->readScriptFile(luaFile));
	}
	else
	{
		Ogre::LogManager::getSingletonPtr()->logMessage(Ogre::LML_NORMAL,Ogre::String("Opening lua file: ")+luaFile);
		s = luaL_dofile(LuaState, luaFile.c_str());
	}
	if(s != 0)
	{
		std::string errs = lua_tostring(LuaState, -1);
		//MessageBoxA( NULL, errs.c_str(), "Script error!", MB_OK);
		Ogre::LogManager::getSingleton().logMessage(Ogre::LML_CRITICAL,errs.c_str());
		exit(-1);
	}
}



//-------------------------------------------------------------------------------------

void Game::SetAmbientLightColor(float r,float g, float b){
	mSceneMgr->setAmbientLight(Ogre::ColourValue(r, g, b));
}
//-------------------------------------------------------------------------------------
void Game::createSceneNode(luabind::object pos,luabind::object ori,luabind::object scale,luabind::object initializer)
{
	float x =luabind::object_cast<float>(pos["x"]);
	float y =luabind::object_cast<float>(pos["y"]);
	float z =luabind::object_cast<float>(pos["z"]);

	float pitch =luabind::object_cast<float>(ori["x"]);
	float yaw =luabind::object_cast<float>(ori["y"]);
	float roll =luabind::object_cast<float>(ori["z"]);

	float sx =luabind::object_cast<float>(scale["x"]);
	float sy =luabind::object_cast<float>(scale["y"]);
	float sz =luabind::object_cast<float>(scale["z"]);

	Ogre::SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
	Ogre::SceneNode* newControlNode = controlSceneManager->getRootSceneNode()->createChildSceneNode();
	node->setPosition(x,y,z);
	node->scale(sx,sy,sz);
	newControlNode->setPosition(x,y,z);
	newControlNode->scale(sx,sy,sz);

	node->roll(Ogre::Degree(roll));
	node->yaw(Ogre::Degree(yaw));
	node->pitch(Ogre::Degree(pitch));

	newControlNode->roll(Ogre::Degree(roll));
	newControlNode->yaw(Ogre::Degree(yaw));
	newControlNode->pitch(Ogre::Degree(pitch));

	initializer(node,newControlNode);
}
/*
void Game::createSceneNode(Ogre::String nodeName, Ogre::String controlNodeName,
Ogre::Vector3 pos = Ogre::Vector3.ZERO,
Ogre::Vector3 ori = Ogre::Vector3.ZERO,
Ogre::Vector3 scale = Ogre::Vector3(1,1,1))
{
Ogre::SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode(nodeName);
Ogre::SceneNode* newControlNode = controlSceneManager->getRootSceneNode()->createChildSceneNode(controlNodeName);

node->setPosition(pos);
node->scale(scale);

newControlNode->setPosition(pos);
newControlNode->scale(scale);

float pitch = ori.x;
float yaw = ori.y;
float roll = ori.z;

node->roll(Ogre::Degree(roll));
node->yaw(Ogre::Degree(yaw));
node->pitch(Ogre::Degree(pitch));

newControlNode->roll(Ogre::Degree(roll));
newControlNode->yaw(Ogre::Degree(yaw));
newControlNode->pitch(Ogre::Degree(pitch));

// initializer(node,newControlNode);
}
*/
//-------------------------------------------------------------------------------------
void Game::addSceneNode(Ogre::SceneNode *node,Ogre::SceneNode *controlnode,luabind::object pos,luabind::object ori,luabind::object scale,luabind::object initializer)
{
	Ogre::SceneNode* childnode = node->createChildSceneNode();
	Ogre::SceneNode* childcontrolnode = controlnode->createChildSceneNode();
	float x =luabind::object_cast<float>(pos["x"]);
	float y =luabind::object_cast<float>(pos["y"]);
	float z =luabind::object_cast<float>(pos["z"]);

	float pitch =luabind::object_cast<float>(ori["x"]);
	float yaw =luabind::object_cast<float>(ori["y"]);
	float roll =luabind::object_cast<float>(ori["z"]);

	float sx =luabind::object_cast<float>(scale["x"]);
	float sy =luabind::object_cast<float>(scale["y"]);
	float sz =luabind::object_cast<float>(scale["z"]);

	childnode->setPosition(x,y,z);
	childnode->scale(sx,sy,sz);
	childcontrolnode->setPosition(x,y,z);
	childcontrolnode->scale(sx,sy,sz);

	childnode->roll(Ogre::Degree(roll));
	childnode->yaw(Ogre::Degree(yaw));
	childnode->pitch(Ogre::Degree(pitch));

	childcontrolnode->roll(Ogre::Degree(roll));
	childcontrolnode->yaw(Ogre::Degree(yaw));
	childcontrolnode->pitch(Ogre::Degree(pitch));


	initializer(childnode,childcontrolnode);
}

//-------------------------------------------------------------------------------------

void Game::addStaticEntity(Ogre::SceneNode *node,luabind::object param)

{

	std::string name = luabind::object_cast<std::string>(param["name"]);
	std::string mesh = luabind::object_cast<std::string>(param["mesh"]);
	Ogre::Entity * entity = mSceneMgr->createEntity(name,mesh);

	entity->setCastShadows(true);

	node->attachObject(entity);

}


void Game::addEntity(const Ogre::String &entityName, Ogre::SceneNode* node, Ogre::SceneNode* controlNode, luabind::object param,luabind::object initializer)
{
	std::string controlLogicName = luabind::object_cast<std::string>(param["controlLogic"]);


	// Cast to EntityControl beacause the control method
	EntityControl* newControlEntity = new EntityControl(entityName);
	//Ogre::SceneNode* newControlNode = controlNode->createChildSceneNode(entityName + "Node");
	controlSceneManager->injectMovableObject(newControlEntity);
	//controlEntityList.push_back(newControlEntity);

	controlNode->attachObject(newControlEntity);

	newControlEntity->addController(controlLogics[controlLogicName]);

	initializer(newControlEntity,node,controlNode);


}

void Game::addPhysicsBody(EntityControl *entity,Ogre::SceneNode* node,luabind::object param,luabind::object initializer)
{
	int collisionGroup = luabind::object_cast<int>(param["collisionGroup"]);
	float weight = luabind::object_cast<float>(param["weight"]);
	float box = luabind::object_cast<float>(param["boundingBox"]);
	bool isStatic = luabind::object_cast<bool>(param["isStatic"]);
	bool isKinematic = luabind::object_cast<bool>(param["isKinematic"]);
	bool disableGravity = luabind::object_cast<bool>(param["disableGravity"]);
	std::string actorD = luabind::object_cast<std::string>(param["actorDesc"]);


	UltimatePhysicsActorDesc  *actorDesc;

	actorDesc = actorDescMap[actorD];


	PhysicsEntityBody * physicsBody = new PhysicsEntityBody(actorDesc, mPhysicsScene,node,isKinematic, isStatic, collisionGroup);

	if(disableGravity)
	{
		physicsBody->disableGravity();
	}

	entity->addBody(physicsBody);



	Ogre::String * name = new Ogre::String(entity->getName());

	physicsBody->setEntityNameForUserData(name);

	initializer( (EntityBody*)physicsBody);
}

void Game::addOgreBody(EntityControl *entity,Ogre::SceneNode* node,luabind::object param,luabind::object initializer)
{

	std::string mesh = luabind::object_cast<std::string>(param["mesh"]);

	// Create the Model for default SceneManager
	Ogre::Entity* newModelEntity = mSceneMgr->createEntity(entity->getName(), mesh);
	node->attachObject(newModelEntity);

	OgreEntityBody * ogreBody = new OgreEntityBody(newModelEntity, mSceneMgr);

	entity->addBody(ogreBody);

	initializer((EntityBody*)ogreBody);

}

void Game::addParticleSystemBody(EntityControl *entity,Ogre::SceneNode* node,luabind::object param,luabind::object initializer)
{
	std::string name = luabind::object_cast<std::string>(param["name"]);
	Ogre::String script= luabind::object_cast<Ogre::String>(param["script"]);

	ParticleEntityBody * psBody = new ParticleEntityBody(node,mSceneMgr,script,name+entity->getName(), &pSystems);


	entity->addBody(psBody);

	initializer((EntityBody*)psBody);

}


void Game::addNodeBody(EntityControl *entity,Ogre::SceneNode* node,luabind::object param,luabind::object initializer)
{
	std::string name = luabind::object_cast<std::string>(param["name"]);


	NodeEntityBody* nodeBody = new NodeEntityBody(node, mSceneMgr);
	entity->addBody(nodeBody);

	initializer((EntityBody*)nodeBody);

}

void Game::setMasterBody(EntityControl *entity,EntityBody * body)
{

	entity->setMasterBody(body);

}

void Game::addController(EntityControl *entity,Ogre::String controlLogicName)
{
	entity->addController(controlLogics[controlLogicName]);
}



void Game::addPhysicsEntity(const Ogre::String &entityName, Ogre::SceneNode* node, Ogre::SceneNode* controlNode, luabind::object param,luabind::object initializer)
{
	std::string controlLogicName = luabind::object_cast<std::string>(param["controlLogic"]);
	std::string mesh = luabind::object_cast<std::string>(param["mesh"]);
	int collisionGroup = luabind::object_cast<int>(param["collisionGroup"]);
	float weight = luabind::object_cast<float>(param["weight"]);
	float box = luabind::object_cast<float>(param["boundingBox"]);
	bool isStatic = luabind::object_cast<bool>(param["isStatic"]);
	bool isKinematic = luabind::object_cast<bool>(param["isKinematic"]);
	std::string actorD = luabind::object_cast<std::string>(param["actorDesc"]);

	// Create the Model for default SceneManager
	Ogre::Entity* newModelEntity = mSceneMgr->createEntity(entityName, mesh);
	//Ogre::SceneNode* newModelNode = node->createChildSceneNode(entityName + "Node");
	node->attachObject(newModelEntity);


	// Create Control for the ControlSceneManager
	/*Ogre::Entity* newEntity = controlSceneManager->createEntity(entityName, mesh);
	newEntity->setCastShadows(true);*/
	// Cast to EntityControl beacause the control method

	/*EntityControl* newControlEntity = allocateObject<EntityControl,1000>("EntityControl");

	*newControlEntity = EntityControl(entityName);*/

	EntityControl* newControlEntity = new EntityControl(entityName);

	//Ogre::SceneNode* newControlNode = controlNode->createChildSceneNode(entityName + "Node");
	controlSceneManager->injectMovableObject(newControlEntity);
	//controlEntityList.push_back(newControlEntity);

	controlNode->attachObject(newControlEntity);

	OgreEntityBody * ogreBody = new OgreEntityBody(newModelEntity, mSceneMgr);

	// Set Model to Control
	//newControlEntity->setModelActor(newModelEntity );
	newControlEntity->addBody(ogreBody);

	//Create the Physics for the default SceneManager
	//PhysicsEntity* newPhysicsEntity = new PhysicsEntity(mWorld, mBodies, mShapes, newControlEntity, node, weight ,box);
	initializer(newControlEntity, node,controlNode);

	UltimatePhysicsActorDesc * actorDesc = mPhysicsScene->createPhysicsActorDesc();

	if(actorD == "_boundingBox")
	{

		Ogre::Vector3 boxSize = newModelEntity->getBoundingBox().getSize();



		/*NxBoxShapeDesc *boxShape =new NxBoxShapeDesc();
		boxShape->localPose.t.set(0,0,0);
		boxShape->dimensions.set(boxSize.x*0.7,boxSize.y*0.7,boxSize.z*0.7);


		actorDesc.shapes.pushBack(boxShape);*/
		actorDesc->addBoxShape(Ogre::Vector3(0,0,0), Ogre::Vector3(0,0,0),Ogre::Vector3(boxSize.x*box,boxSize.y*box,boxSize.z*box));
	}
	else
	{
		actorDesc = actorDescMap[actorD];
	}
	//NxBoxShapeDesc *boxShape = new NxBoxShapeDesc();
	//boxShape->dimensions.set(box,box,box);

	//actorDesc.shapes.pushBack(boxShape);
	//PhysicsEntity* newPhysicsEntity = new PhysicsEntity(node,&actorDesc, mNxScene,isKinematic, isStatic, collisionGroup);

	//TODO add weight
	PhysicsEntityBody * physicsBody = new PhysicsEntityBody(actorDesc, mPhysicsScene,node,isKinematic, isStatic, collisionGroup);
	//delete actorDesc;
	//node->attachObject(newPhysicsEntity);
	//mNumEntitiesInstanced++;

	// Set Phy to Control
	//newControlEntity->setPhysicsActor(newPhysicsEntity);
	newControlEntity->setMasterBody(physicsBody);

	Ogre::String * name = new Ogre::String(newControlEntity->getName());

	//Setting user data for collisions
	//newPhysicsEntity->getNxActor()->userData = name;
	physicsBody->setEntityNameForUserData(name);

	// ControlLogic
	newControlEntity->addController(controlLogics[controlLogicName]);


}

void Game::addProjectile(
	Controller::Projectile projectile,
	Ogre::SceneNode* node,
	Ogre::SceneNode* controlNode,
	std::string controlLogicName)
{
	// Create the Model for default SceneManager
	Ogre::Entity* newModelEntity = mSceneMgr->createEntity("projectile"+Ogre::StringConverter::toString(projectileCount),projectile.modelMeshName);
	//Ogre::SceneNode* newModelNode = node->createChildSceneNode("projectile"+Ogre::StringConverter::toString(projectileCount) + "Node");


	node->scale(projectile.scale);
	node->pitch(Ogre::Degree(projectile.rotate.x));
	node->yaw(Ogre::Degree(projectile.rotate.y));
	node->roll(Ogre::Degree(projectile.rotate.z));

	node->attachObject(newModelEntity);

	// Create Control for the ControlSceneManager
	//Ogre::Entity* newEntity = controlSceneManager->createEntity("projectile"+Ogre::StringConverter::toString(projectileCount),modelMeshName);



	// Cast to EntityControl beacause the control method
	/*EntityControl* newControlEntity = allocateObject<EntityControl,1000>("EntityControl");

	*newControlEntity = EntityControl("projectile"+Ogre::StringConverter::toString(projectileCount));*/
	std::string entityName ="projectile"+Ogre::StringConverter::toString(projectileCount);
	EntityControl* newControlEntity = new EntityControl(entityName);



	//Ogre::SceneNode* newControlNode = controlNode->createChildSceneNode(entityName + "Node");
	controlNode->attachObject(newControlEntity);
	controlSceneManager->injectMovableObject(newControlEntity);

	OgreEntityBody * ogreBody = new OgreEntityBody(newModelEntity, mSceneMgr);

	// Set Model to Control
	//newControlEntity->setModelActor(newModelEntity );
	newControlEntity->addBody(ogreBody);
	newControlEntity->setCastShadows(true);

	//Create the Physics for the default SceneManager
	//PhysicsEntity* newPhysicsEntity = new PhysicsEntity(mWorld, mBodies, mShapes, newControlEntity, node);

	UltimatePhysicsActorDesc * actorDesc = mPhysicsScene->createPhysicsActorDesc();

	//NxBoxShapeDesc *boxShape = new NxBoxShapeDesc();
	////boxShape->dimensions.set(2.0,2.0,2.0);
	//boxShape->dimensions.set((newModelEntity->getBoundingBox().getHalfSize().x)*0.2,(newModelEntity->getBoundingBox().getHalfSize().y)*0.2,(newModelEntity->getBoundingBox().getHalfSize().z)*0.2);
	//actorDesc.shapes.pushBack(boxShape);
	/*NxSphereShapeDesc *sphereDesc = new NxSphereShapeDesc();
	sphereDesc->radius = (newModelEntity->getBoundingRadius()*0.1);
	actorDesc.shapes.pushBack(sphereDesc);
	*/

	Ogre::Vector3 boxSize = newModelEntity->getBoundingBox().getSize();

	actorDesc->addBoxShape(Ogre::Vector3(0,0,0),Ogre::Vector3(0,0,0), Ogre::Vector3(boxSize.x,boxSize.y,boxSize.z));



	//PhysicsEntity* newPhysicsEntity = new PhysicsEntity(node, &actorDesc,mNxScene,false, false, 3);
 	PhysicsEntityBody * physicsBody = new PhysicsEntityBody(actorDesc, mPhysicsScene,node,false, false, projectile.collisionGroup,100000);
	//delete actorDesc;
	//node->attachObject(newPhysicsEntity);
	//mNumEntitiesInstanced++;

	// Initial speed
	//newPhysicsEntity->set
	//velocity = velocity;
	physicsBody->addForce(projectile.velocity);
	physicsBody->disableGravity();


	Ogre::String * name = new Ogre::String(newControlEntity->getName());
	//Setting user data for collisions
	//newPhysicsEntity->getNxActor()->userData = name;
	physicsBody->setEntityNameForUserData(name);

	// Set Phy to Control
	//newControlEntity->setPhysicsActor(newPhysicsEntity);
	newControlEntity->setMasterBody(physicsBody);
	newControlEntity->addBody(physicsBody);
	// ControlLogic
	newControlEntity->addController(controlLogics[controlLogicName]);
	
	if(projectile.particleSystemAdded)
	{
		ParticleEntityBody * psBody = new ParticleEntityBody(node,mSceneMgr,projectile.parcticelSystemName,entityName+"Particle",&pSystems);


		newControlEntity->addBody(psBody);
	}

	Trigger *farTrigger = new Trigger(); 
	farTrigger->addRequiement(new NegateReq(new PositionReq(node->getPosition(),5000)));
	farTrigger->addAction(new DeleteAction());
	newControlEntity->AddTrigger(farTrigger);

	if(projectileCount>=maxProjectileCount && controlSceneManager->hasManualObject("projectile"+Ogre::StringConverter::toString(projectileCount-maxProjectileCount)))
	{

		EntityControl* deleteProjectile=(EntityControl*)controlSceneManager->getManualObject("projectile"+Ogre::StringConverter::toString(projectileCount-maxProjectileCount));

		Trigger *deleteTrigger = new Trigger(); 
		deleteTrigger->addAction(new DeleteAction());
		deleteProjectile->AddTrigger(deleteTrigger);

	}

	projectileCount++;

}

void Game::setMaxProjectileCount(int max)
{
	maxProjectileCount = max;
}

void Game::addPhysicsTerrain(const Ogre::String &entityName, Ogre::SceneNode* node, Ogre::SceneNode* controlNode, luabind::object param)
	//const Ogre::String &mesh, std::string controlLogicName
{
	///////////////////////////////FLOOR PLANE\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

	std::string controlLogicName = luabind::object_cast<std::string>(param["controlLogic"]);
	int collisionGroup = luabind::object_cast<int>(param["collisionGroup"]);

	// Define a floor plane mesh
	Ogre::MovablePlane *p= new Ogre::MovablePlane("GroundPlane");
	p->normal = Ogre::Vector3::UNIT_Y; p->d = 0;
	Ogre::MeshManager::getSingleton().createPlane("FloorPlane", 
		Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, 
		*p, 500, 500, 1,1, true, 1, 10, 10, 
		Ogre::Vector3::UNIT_Z);

	// Create the Model entity (the floor)
	Ogre::Entity* newModelEntity = mSceneMgr->createEntity(entityName, "FloorPlane");
	newModelEntity->setMaterialName("stone");
	Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().getByName("TerrainMaterial/TerrainPlane");
	newModelEntity->setCastShadows(false);
	node->attachObject(newModelEntity);

	mPhysicsScene->createPhysicsPlane(node->getPosition().y+3, collisionGroup);

	/*NxPlaneShapeDesc planeDesc;
	planeDesc.d = node->getPosition().y+3;
	planeDesc.group = collisionGroup;
	NxActorDesc actorDesc, actorDesc2;
	actorDesc.shapes.pushBack(&planeDesc);
	mNxScene->createActor(actorDesc);
	*/


	/*test = new Terrain(mSceneMgr, light);
	test->createTerrain(mPhysicsSDK,mNxScene);*/



}
void Game::setEntityStatus(EntityControl *entity, std::string status)
{
	if(status=="WAITING")
	{
		entity->wait();

	}else if(status=="PLAYING")
	{
		entity->play();

	}else if(status=="DEAD")
	{
		entity->DDDIIIE();

	}else if(status=="GAMEOVER")
	{
		entity->GameOverMan();

	}


}


void Game::bindButtonKey(std::string abstractKeyName, int keyId)
{
	controlStatus.bindKey( abstractKeyName,  keyId);
}

void Game::bindKey(std::string abstractKeyName, std::string keyId)
{
	controlStatus.bindKey( abstractKeyName,  keyId);
}


//Local function for curve generation to make it easier to reuse
std::vector<Ogre::Vector3*>* Game::calcCurve(luabind::object param)
{

	// mapBasePoints structure
	luabind::object mapBasePoints = luabind::object_cast<luabind::object>(param["mapBasePoints"]);

	// number of mapBasePoints
	int numberOfMapBasePoints = luabind::object_cast<int>(mapBasePoints["numberOfPoints"]);

	// Get the points to basePoints
	std::vector<Ogre::Vector3*> basePoints;
	for( int i = 1; i <= numberOfMapBasePoints; i++)
	{
		/*
		// Get "point i" string
		std::string pointI;
		std::stringstream out;
		out << "point";
		out << i;
		pointI = out.str();

		Ogre::StringConverter::toString(i);
		*/

		// Get the ith point
		luabind::object luaPoint = luabind::object_cast<luabind::object>(mapBasePoints["point" + Ogre::StringConverter::toString(i)]);
		float x = luabind::object_cast<float>(luaPoint["x"]);
		float y = luabind::object_cast<float>(luaPoint["y"]);
		float z = luabind::object_cast<float>(luaPoint["z"]);
		Ogre::Vector3* point = new Ogre::Vector3(x,y,z);

		// Add the point
		basePoints.push_back(point);
	}

	// curveResolution
	float curveResolution = luabind::object_cast<float>(param["resolution"]);

	// Generate its rail
	return CurveGenerator::generateCurve(&basePoints, curveResolution);
}


void Game::addBodyRailControlLogic(std::string name,luabind::object param)
{


	// Create BodyRailControlLogic
	BodyRailControlLogic* bodyRailControlLogic = new BodyRailControlLogic();

	std::vector<Ogre::Vector3*> *curvePoints = calcCurve(param);

	bodyRailControlLogic->setRail(curvePoints);

	// Register BodyRailControlLogic
	controlLogics[name] = bodyRailControlLogic;

	int f = 8;

}

void Game::addTargetControlLogic(std::string name,luabind::object param,luabind::object initializer)
{

	float maxForce = luabind::object_cast<float>(param["maxForce"]);
	float maxTorque = luabind::object_cast<float>(param["maxTorque"]);

	// Create TargetControlLogic
	TargetControlLogic* targetControlLogic = new TargetControlLogic(maxForce, maxTorque);
	// Register TargetControlLogic
	controlLogics[name] = targetControlLogic;

	initializer(targetControlLogic);
}

void Game::addTarget(TargetControlLogic* targetControlLogic,luabind::object param)
{

	luabind::object luaPos = luabind::object_cast<luabind::object>(param["position"]);
	float x = luabind::object_cast<float>(luaPos["x"]);
	float y = luabind::object_cast<float>(luaPos["y"]);
	float z = luabind::object_cast<float>(luaPos["z"]);
	Ogre::Vector3 position = Ogre::Vector3(x,y,z);

	float proximityRadius = luabind::object_cast<float>(param["proximityRadius"]);
	std::string name = luabind::object_cast<std::string>(param["name"]);

	// Create Target
	Target* target = new Target(position, proximityRadius);



	// Set Mark
	if(mSceneMgr->hasEntity(name))
		target->setMark(mSceneMgr->getEntity(name));
	else
		target->setMark(NULL);

	//WeakDirectory<Entity>::iterator iEntity = entityDirectory.find( parameters.getString("mark", "nommark_absolute") );
	//if(iEntity != entityDirectory.end())
	//	if(!iEntity->second.expired())
	//		target->setMark(iEntity->second.lock());

	// Adding target to TargetControlLogic
	targetControlLogic->addTarget( target );
}

void Game::addProjectileTarget(TargetControlLogic* targetControlLogic,luabind::object param)
{

	luabind::object luaPos = luabind::object_cast<luabind::object>(param["position"]);
	float x = luabind::object_cast<float>(luaPos["x"]);
	float y = luabind::object_cast<float>(luaPos["y"]);
	float z = luabind::object_cast<float>(luaPos["z"]);
	Ogre::Vector3 position = Ogre::Vector3(x,y,z);

	float proximityRadius = luabind::object_cast<float>(param["proximityRadius"]);
	std::string name = luabind::object_cast<std::string>(param["name"]);

	// Create Target
	Target* target = new Target(position, proximityRadius);



	// Set Mark
	if(mSceneMgr->hasEntity(name))
		target->setMark(mSceneMgr->getEntity(name));
	else
		target->setMark(NULL);

	//WeakDirectory<Entity>::iterator iEntity = entityDirectory.find( parameters.getString("mark", "nommark_absolute") );
	//if(iEntity != entityDirectory.end())
	//	if(!iEntity->second.expired())
	//		target->setMark(iEntity->second.lock());

	// Adding target to TargetControlLogic
	targetControlLogic->addProjectileTarget( target );
}

void Game::addLauncher(TargetControlLogic* targetControlLogic, luabind::object param)
{
	std::string mesh = luabind::object_cast<std::string>(param["mesh"]);
	Ogre::String meshName = mesh;

	luabind::object luaPos = luabind::object_cast<luabind::object>(param["position"]);
	float x = luabind::object_cast<float>(luaPos["x"]);
	float y = luabind::object_cast<float>(luaPos["y"]);
	float z = luabind::object_cast<float>(luaPos["z"]);
	Ogre::Vector3 position = Ogre::Vector3(x,y,z);

	luabind::object luaVel = luabind::object_cast<luabind::object>(param["velocity"]);
	float vx = luabind::object_cast<float>(luaVel["x"]);
	float vy = luabind::object_cast<float>(luaVel["y"]);
	float vz = luabind::object_cast<float>(luaVel["z"]);
	Ogre::Vector3 velocity = Ogre::Vector3(vx,vy,vz);

	luabind::object luaVScale = luabind::object_cast<luabind::object>(param["scale"]);
	float sx = luabind::object_cast<float>(luaVScale["x"]);
	float sy = luabind::object_cast<float>(luaVScale["y"]);
	float sz = luabind::object_cast<float>(luaVScale["z"]);
	Ogre::Vector3 scale = Ogre::Vector3(sx,sy,sz);

	luabind::object luaRotate = luabind::object_cast<luabind::object>(param["rotation"]);
	float rx = luabind::object_cast<float>(luaRotate["x"]);
	float ry = luabind::object_cast<float>(luaRotate["y"]);
	float rz = luabind::object_cast<float>(luaRotate["z"]);
	Ogre::Vector3 rotate = Ogre::Vector3(rx,ry,rz);

	std::string particleSystem = luabind::object_cast<std::string>(param["particle"]);

	int collisionGroup = luabind::object_cast<int>(param["collisionGroup"]);

	float cooldown = luabind::object_cast<float>(param["cooldown"]);

	Controller::Projectile newProjectile;
	newProjectile.modelMeshName=mesh;

	if(particleSystem=="no_particle")
	{
		newProjectile.particleSystemAdded=false;
	}
	else
	{
		newProjectile.particleSystemAdded=true;
		newProjectile.parcticelSystemName=particleSystem;
	}
	newProjectile.position = position;
	newProjectile.rotate = rotate;
	newProjectile.scale = scale;
	newProjectile.velocity = velocity;
	newProjectile.collisionGroup = collisionGroup;

	// Create Launcher
	Launcher* launcher = new Launcher(newProjectile, cooldown);

	// Adding launcher to TargetControlLogic
	targetControlLogic->addLauncher( launcher );
}

void Game::createActorDesc(luabind::object param,luabind::object initializer)
{
	Ogre::String name = luabind::object_cast<Ogre::String>(param["name"]);

	UltimatePhysicsActorDesc *actorDesc = mPhysicsScene->createPhysicsActorDesc();

	actorDescMap[name] = actorDesc;

	/*boxShapeVector.clear();*/

	initializer(name);

	//actorDescMap[name]->addBoxShape(boxShapeDesc[0],boxShapeDesc[1],boxShapeDesc[2]);

	//NxBoxShapeDesc sd = NxBoxShapeDesc();

}

void Game::addBoxShapeDesc(std::string name,luabind::object param)
{
	luabind::object luaPos = luabind::object_cast<luabind::object>(param["position"]);
	float x = luabind::object_cast<float>(luaPos["x"]);
	float y = luabind::object_cast<float>(luaPos["y"]);
	float z = luabind::object_cast<float>(luaPos["z"]);


	luabind::object luaRot = luabind::object_cast<luabind::object>(param["rotation"]);
	float rx = luabind::object_cast<float>(luaRot["x"]);
	float ry = luabind::object_cast<float>(luaRot["y"]);
	float rz = luabind::object_cast<float>(luaRot["z"]);


	luabind::object luaDim = luabind::object_cast<luabind::object>(param["dimension"]);
	float dx = luabind::object_cast<float>(luaDim["x"]);
	float dy = luabind::object_cast<float>(luaDim["y"]);
	float dz = luabind::object_cast<float>(luaDim["z"]);

	boxShapeDesc[0] = *new Ogre::Vector3(x,y,z);
	boxShapeDesc[1] = *new Ogre::Vector3(rx,ry,rz);
	boxShapeDesc[2] = *new Ogre::Vector3(dx,dy,dz);
	//boxShapeVector.push_back();

	actorDescMap[name]->addBoxShape(Ogre::Vector3(x,y,z),Ogre::Vector3(rx,ry,rz),Ogre::Vector3(dx,dy,dz));
}

//----------------------------------------------------------------------------------------------
// Audio specific functions
// Megjegyzes: lehet h ezeket ki kene szervezni kulon osztalyba mert kesobb nehezkes a bovitese
// Most a OpenAL - Game - LUA indirekcio 3-as van, lehet h mar ez is felesleges
//----------------------------------------------------------------------------------------------
Ogre::Vector3 Game::getAudioListenerPosition()
{
	return gameAudio->getAudioListenerPosition();
}
//----------------------------------------------------------------------------------------------
Ogre::Vector3 Game::getAudioListenerDirection()
{
	return gameAudio->getAudioListenerDirection();
}
//----------------------------------------------------------------------------------------------
void Game::setAudioListenerPose(Ogre::Vector3 pos, Ogre::Vector3 dir)
{
	//float x = luabind::object_cast<float>(position["x"]);
	//float y = luabind::object_cast<float>(position["y"]);
	//float z = luabind::object_cast<float>(position["z"]);

	gameAudio->setAudioListenerPose(pos, dir);
}
//----------------------------------------------------------------------------------------------
void Game::createAudioWithName(
	Ogre::String name, Ogre::String filePath, bool looping,
	float pitch, luabind::object position)
{
	float x = luabind::object_cast<float>(position["x"]);
	float y = luabind::object_cast<float>(position["y"]);
	float z = luabind::object_cast<float>(position["z"]);

	gameAudio->createAudioWithName(name, filePath, looping, pitch, Ogre::Vector3(x, y, z));

}
//----------------------------------------------------------------------------------------------
void Game::setAudioWithName(
	Ogre::String name, Ogre::String filePath, bool looping,
	float pitch, luabind::object position)
{
	float x = luabind::object_cast<float>(position["x"]);
	float y = luabind::object_cast<float>(position["y"]);
	float z = luabind::object_cast<float>(position["z"]);

	gameAudio->setAudioWithName(name, filePath, looping, pitch, Ogre::Vector3(x, y, z));

}

//----------------------------------------------------------------------------------------------
void Game::playAudioByName(Ogre::String name)
{
	gameAudio->playAudioByName(name);
}

//----------------------------------------------------------------------------------------------
void Game::playAudioFromFile(Ogre::String filePath, bool looping,
	float pitch, luabind::object position)
{
	float x = luabind::object_cast<float>(position["x"]);
	float y = luabind::object_cast<float>(position["y"]);
	float z = luabind::object_cast<float>(position["z"]);

	gameAudio->playAudioFromFile(filePath, looping, pitch, Ogre::Vector3(x, y, z));
}

//----------------------------------------------------------------------------------------------
void Game::stopAudioByName(Ogre::String name)
{
	gameAudio->stopAudioByName(name);
}

//----------------------------------------------------------------------------------------------
void Game::stopAllAudioSource()
{
	gameAudio->stopAllAudioSource();
}

//----------------------------------------------------------------------------------------------
void Game::deleteAllAudioSource()
{
	gameAudio->deleteAllAudioSource();
}
//----------------------------------------------------------------------------------------------

void Game::addTrigger(EntityControl *ent,luabind::object initializer)
{
	//EntityControl *ent =static_cast<EntityControl*>( controlSceneManager->getEntity(name));
	Trigger *tr = new Trigger();

	initializer(tr);
	ent->AddTrigger(tr);
}
//----------------------------------------------------------------------------------------------
void Game::createDamageAction(Trigger *tr, luabind::object param)
{
	float damage = luabind::object_cast<float>(param["damage"]);
	DamageAction *da = new DamageAction(damage);
	tr->addAction(da);
}
//----------------------------------------------------------------------------------------------
void Game::createGameOverAction(Trigger *tr)
{

	GameOverAction * ga =new GameOverAction();
	//*ga = GameOverAction();

	tr->addAction(ga);
}
//----------------------------------------------------------------------------------------------
void Game::createKillAction(Trigger *tr,std::string entityName)
{
	EntityControl * targetEntity = (EntityControl*) controlSceneManager->getManualObject(entityName);
	tr->addAction(new KillAction(targetEntity));

}
//----------------------------------------------------------------------------------------------
void Game::createKilledReq(Trigger *tr)
{
	KilledReq *kr = new KilledReq();
	tr->addRequiement(kr);
}
//----------------------------------------------------------------------------------------------
void Game::createExplodeAction(Trigger *tr)
{
	ExplodeAction* ea = new ExplodeAction();
	tr->addAction(ea);
}
//----------------------------------------------------------------------------------------------
void Game::createPositionReq(Trigger *tr, luabind::object param)
{
	float x = luabind::object_cast<float>(param["x"]);
	float y = luabind::object_cast<float>(param["y"]);
	float z = luabind::object_cast<float>(param["z"]);
	float radius = luabind::object_cast<float>(param["radius"]);
	PositionReq *pr = new PositionReq(Ogre::Vector3(x,y,z),radius);
	tr->addRequiement(pr);
}
//----------------------------------------------------------------------------------------------
void Game::createFreeRayReq(Trigger *tr, luabind::object param)
{
	luabind::object luaPos = luabind::object_cast<luabind::object>(param["position"]);
	float x = luabind::object_cast<float>(luaPos["x"]);
	float y = luabind::object_cast<float>(luaPos["y"]);
	float z = luabind::object_cast<float>(luaPos["z"]);


	luabind::object luaRot = luabind::object_cast<luabind::object>(param["direction"]);
	float dx = luabind::object_cast<float>(luaRot["x"]);
	float dy = luabind::object_cast<float>(luaRot["y"]);
	float dz = luabind::object_cast<float>(luaRot["z"]);

	float dist = luabind::object_cast<float>(param["distance"]);

	tr->addRequiement(new FreeRayReq(mRaySceneQuery,Ogre::Vector3(x,y,z), Ogre::Vector3(dx,dy,dz),dist));


}
//----------------------------------------------------------------------------------------------
void Game::createPSysAction(Trigger *tr, luabind::object param )
{
	Ogre::String script= luabind::object_cast<Ogre::String>(param["script"]);
	tr->addAction(new PSysAction(mSceneMgr,script, &pSystems));
}

//----------------------------------------------------------------------------------------------
void Game::createCustomScriptAction(Trigger *tr,luabind::object param)
{
	tr->addAction(new CustomScriptAction(param));
}
//----------------------------------------------------------------------------------------------
void Game::createNegateReq(Trigger *tr, luabind::object initializer)
{
	Trigger dummyTrigger;

	initializer(&dummyTrigger);


	if(dummyTrigger.getRequirements().size()==0)
	{
		return;
	}

	TriggerRequirement * addedReq = dummyTrigger.getRequirements()[0];

	tr->addRequiement(new NegateReq(addedReq));
}
//----------------------------------------------------------------------------------------------

void Game::createFreeMoveAction(Trigger *tr,luabind::object param)
{

	int amount = luabind::object_cast<int>(param["amount"]);



	luabind::object luaDir = luabind::object_cast<luabind::object>(param["direction"]);
	float dx = luabind::object_cast<float>(luaDir["x"]);
	float dy = luabind::object_cast<float>(luaDir["y"]);
	float dz = luabind::object_cast<float>(luaDir["z"]);

	tr->addAction(new FreeMoveAction(Ogre::Vector3(dx,dy,dz),amount));

}
//----------------------------------------------------------------------------------------------
void Game::createOnRailMoveAction(Trigger *tr,luabind::object map)
{
	std::vector<Ogre::Vector3*> * mapPoints = calcCurve(map);

	tr->addAction(new OnRailMoveAction(mapPoints));
}

//----------------------------------------------------------------------------------------------
void Game::setCamera(Ogre::SceneNode* node)
{
	node->attachObject(mCamera);
}
//----------------------------------------------------------------------------------------------
void Game::SetRoundCamera(luabind::object param)
{
	float radius = luabind::object_cast<float>(param["radius"]);
	float height = luabind::object_cast<float>(param["height"]);
	Ogre::String target = luabind::object_cast<Ogre::String>(param["target"]);
	luabind::object luaPos = luabind::object_cast<luabind::object>(param["position"]);
	float x = luabind::object_cast<float>(luaPos["x"]);
	float y = luabind::object_cast<float>(luaPos["y"]);
	float z = luabind::object_cast<float>(luaPos["z"]);

	rCamera = new RoundCamera(mSceneMgr, height,radius, Ogre::Vector3(x,y,z),target);

}
//----------------------------------------------------------------------------------------------
void Game::createCamera(Ogre::SceneNode* node,luabind::object param)
{
	std::string name = luabind::object_cast<std::string>(param["name"]);
	Ogre::Camera * cam = mSceneMgr->createCamera(name);
	node->attachObject(cam);
	cam->setPosition(Ogre::Vector3(0, 0, 150));
	cam->lookAt(Ogre::Vector3(0, 0, 0));
	cam->setNearClipDistance(1.0f);
	cam->setFarClipDistance(100000.0f);
	cam->setAutoAspectRatio(true);
	//entity->setCamera(cam);


}

//bool Game::luaFuncCaller(const CEGUI::EventArgs &e)
//{
//	
//	return true;
//}

//----------------------------------------------------------------------------------------------
void Game::bindFunctionGUI(const Ogre::String button, luabind::object f)
{

	/*CEGUI::Window *selectMapButton = CEGUI::WindowManager::getSingleton().getWindow(button);

	LuaFunctionAdapter * func = new LuaFunctionAdapter(f); 
	selectMapButton->subscribeEvent(CEGUI::PushButton::EventClicked,  CEGUI::Event::Subscriber(&LuaFunctionAdapter::callFunction,func));
	*/
}
//----------------------------------------------------------------------------------------------
void Game::loadLayoutGUI(const Ogre::String layout)
{
	/*CEGUI::Window *newWindow = CEGUI::WindowManager::getSingleton().loadWindowLayout(layout);
	CEGUI::System::getSingleton().getGUISheet()->addChildWindow(newWindow);
	newWindow->setVisible(false);*/

}

//----------------------------------------------------------------------------------------------
void Game::setWindowVisible( const Ogre::String window, bool modifier)
{

	/*CEGUI::Window * win = CEGUI::WindowManager::getSingleton().getWindow(window);
	win->setVisible(modifier);*/
}
//----------------------------------------------------------------------------------------------
void Game::setCursorVisible(bool modifier)
{
	/*if(modifier)
	{
	CEGUI::MouseCursor::getSingleton().show();
	}
	else
	{
	CEGUI::MouseCursor::getSingleton().hide();
	}*/

}

//----------------------------------------------------------------------------------------------
void Game::setGravity(float x, float y, float z)
{

	mPhysicsScene->setGravity(x,y,z);

}

//----------------------------------------------------------------------------------------------
void Game::addGameResultEntry(std::string resultName,std::string entityName, std::string parameterName)
{

	std::string * entry = new std::string[3];
	entry[0] =resultName;
	entry[1] =entityName;
	entry[2] =parameterName;

	requiredGameResultList.push_back(entry);


}

//----------------------------------------------------------------------------------------------
EntityParameter* Game::createVectorEntityParameter(std::string name,luabind::object param)
{
	luabind::object luaPos = luabind::object_cast<luabind::object>(param["vector"]);
	float x = luabind::object_cast<float>(luaPos["x"]);
	float y = luabind::object_cast<float>(luaPos["y"]);
	float z = luabind::object_cast<float>(luaPos["z"]);

	return new VectorEntityParameter(name,Ogre::Vector3(x,y,z));

}
//----------------------------------------------------------------------------------------------
void Game::createAIControlLogic(std::string name,luabind::object initializer)
{


	AIControlLogic *AILogic = new AIControlLogic();


	initializer(AILogic);


	controlLogics[name] = AILogic;



}
//----------------------------------------------------------------------------------------------
void Game::addAIGoal(AIControlLogic * logic,luabind::object initializer)
{
	AIGoal * goal = new AIGoal();

	initializer(goal);

	logic->addGoal(goal);
}
//----------------------------------------------------------------------------------------------
void Game::addAIGoalRecord(AIGoal* goal,std::string targetParam, EntityParameter* parameter, luabind::object param)
{
	bool negate = luabind::object_cast<bool>(param["negate"]);
	int offset = luabind::object_cast<int>(param["offset"]);
	int weight = luabind::object_cast<int>(param["weight"]);



	AIGoal::AIGoalRecord * goalRecord = new AIGoal::AIGoalRecord();
	goalRecord->param =targetParam;
	goalRecord->goal = parameter;
	goalRecord->negate = negate;
	goalRecord->offset = offset;
	goalRecord->weight = weight;
	goal->addGoalRecord(goalRecord);


}
//----------------------------------------------------------------------------------------------
void Game::addTriggerToGoal(AIGoal* goal, luabind::object initializer)
{
	//Dirty hack
	EntityControl dummyControl("dummy");
	initializer(&dummyControl);

	for(int i=0; i<dummyControl.getTriggerList().size(); i++)
	{
		goal->addTrigger(dummyControl.getTriggerList()[i]);
	}
}
//----------------------------------------------------------------------------------------------
//Network
void Game::createNetworkContrologic(std::string name, int id, bool serverEntity)
{
	controlLogics[name] = new NetworkControlLogic(id,serverEntity);
}

//----------------------------------------------------------------------------------------------
void Game::setTargetServer(std::string ip, int port)
{
	targetIP=ip;
	targetPort=port;
	isServer=false;
	multiplayer=true;
}

//----------------------------------------------------------------------------------------------
void Game::createServer(int port)
{
	targetPort=port;
	multiplayer=true;
	isServer=true;
}

//----------------------------------------------------------------------------------------------
void Game::startNetworkSession()
{
	if(multiplayer)
	{

		UltimateNetworkSubsystem *networkSubsystem = (UltimateNetworkSubsystem*) UltimateSubsystemRegistry::getSingletonPtr()->getSubsystem(NETWORK_SUBSYSTEM);

		if(isServer)
		{
			networkSubsystem->listenOnPort(targetPort);
		}else
		{
			networkSubsystem->connectToServer(targetIP,targetPort);
		}
	}
}

//----------------------------------------------------------------------------------------------
void Game::stopNetworkSession()
{
	if(multiplayer)
	{
		UltimateNetworkSubsystem *networkSubsystem = (UltimateNetworkSubsystem*) UltimateSubsystemRegistry::getSingletonPtr()->getSubsystem(NETWORK_SUBSYSTEM);

		networkSubsystem->destroyConnection();
	}

}

void Game::addPlayerProjectileControlLogic(std::string name, luabind::object initializer)
{

	PlayerProjectileControlLogic * contoLogic = new PlayerProjectileControlLogic();
	initializer(contoLogic);

	controlLogics[name] = contoLogic;
}

void Game::bindPojectileToKey(PlayerProjectileControlLogic * controLogic,std::string key,luabind::object param)
{
	std::string mesh = luabind::object_cast<std::string>(param["mesh"]);
	Ogre::String meshName = mesh;

	luabind::object luaPos = luabind::object_cast<luabind::object>(param["position"]);
	float x = luabind::object_cast<float>(luaPos["x"]);
	float y = luabind::object_cast<float>(luaPos["y"]);
	float z = luabind::object_cast<float>(luaPos["z"]);
	Ogre::Vector3 position = Ogre::Vector3(x,y,z);

	luabind::object luaVel = luabind::object_cast<luabind::object>(param["velocity"]);
	float vx = luabind::object_cast<float>(luaVel["x"]);
	float vy = luabind::object_cast<float>(luaVel["y"]);
	float vz = luabind::object_cast<float>(luaVel["z"]);
	Ogre::Vector3 velocity = Ogre::Vector3(vx,vy,vz);

	luabind::object luaVScale = luabind::object_cast<luabind::object>(param["scale"]);
	float sx = luabind::object_cast<float>(luaVScale["x"]);
	float sy = luabind::object_cast<float>(luaVScale["y"]);
	float sz = luabind::object_cast<float>(luaVScale["z"]);
	Ogre::Vector3 scale = Ogre::Vector3(sx,sy,sz);

	luabind::object luaRotate = luabind::object_cast<luabind::object>(param["rotation"]);
	float rx = luabind::object_cast<float>(luaRotate["x"]);
	float ry = luabind::object_cast<float>(luaRotate["y"]);
	float rz = luabind::object_cast<float>(luaRotate["z"]);
	Ogre::Vector3 rotate = Ogre::Vector3(rx,ry,rz);

	std::string particleSystem = luabind::object_cast<std::string>(param["particle"]);

	int collisionGroup = luabind::object_cast<int>(param["collisionGroup"]);

	float cooldown = luabind::object_cast<float>(param["cooldown"]);

	Controller::Projectile newProjectile;
	newProjectile.modelMeshName=mesh;

	if(particleSystem=="no_particle")
	{
		newProjectile.particleSystemAdded=false;
	}
	else
	{
		newProjectile.particleSystemAdded=true;
		newProjectile.parcticelSystemName=particleSystem;
	}
	newProjectile.position = position;
	newProjectile.rotate = rotate;
	newProjectile.scale = scale;
	newProjectile.velocity = velocity;
	newProjectile.collisionGroup = collisionGroup;

	// Create Launcher
	Launcher* launcher = new Launcher(newProjectile, cooldown);


	controLogic->addBindProjectileToKey(key, launcher);
}






void Game::setupCollisions()
{
	//// No collision between the sword and its body
	//mNxScene->setGroupCollisionFlag(1,1, false);
	//// sword vs penguin
	//mNxScene->setGroupCollisionFlag(1,2, false);
	//// sword vs projectiles
	//mNxScene->setGroupCollisionFlag(1,3, true);
	//// sword vs enemies
	//mNxScene->setGroupCollisionFlag(1,4, false);

	//// penguins
	//mNxScene->setGroupCollisionFlag(2,2, false);
	//// penguin vs projectiles
	//mNxScene->setGroupCollisionFlag(2,3, true);
	//// penguin vs enemies
	//mNxScene->setGroupCollisionFlag(2,4, false);

	//// projectiles
	//mNxScene->setGroupCollisionFlag(3,3, false);
	//// projectiles vs enemies
	//mNxScene->setGroupCollisionFlag(3,4, false);

}

void Game::addHUD(EntityControl* entity)
{
	/*int hp =((IntEntityParameter*)entity->getParameter(HITPOINT_PARAMETER))->getIntValue();
	mainHUD->refreshHealth(hp);
	mainHUD->setEntity(entity);
	mainHUD->show();*/

}
//static bool myContactAddedCallback(
//	btManifoldPoint& cp,
//	const btCollisionObject* colObj0, int partId0, int index0, 
//	const btCollisionObject* colObj1, int partId1, int index1)
//{
//	EntityControl* entityControl0 = (EntityControl*)colObj0->getCollisionShape()->getUserPointer();
//	EntityControl* entityControl1 = (EntityControl*)colObj1->getCollisionShape()->getUserPointer();
//	if (entityControl0->getCollisionGroupFilter() == entityControl1->getCollisionGroupFilter() )
//	{
//		return false;
//	}
//
//	if (entityControl0->getCollisionGroupFilter() == "TERRAIN" || entityControl1->getCollisionGroupFilter() == "TERRAIN")
//	{}
//	else if (entityControl0->getName() == "Pingvin" && entityControl1->getName() == "kard")
//	{
//		/*Trigger *trigger = new Trigger;
//		DamageAction* damageAction = new DamageAction(20);
//		trigger->addAction(damageAction);
//		entityControl0->AddTrigger(trigger);*/
//	}
//	else if (entityControl0->getName() == "kard" && entityControl1->getName() == "Pingvin")
//	{
//		/*Trigger *trigger = new Trigger;
//		DamageAction* damageAction = new DamageAction(20);
//		trigger->addAction(damageAction);
//		entityControl1->AddTrigger(trigger);*/
//	}
//	else if (entityControl0->getName() == "Pingvin" && entityControl1->getName() != "kard")
//	{
//		if ( !entityControl1->getController()->isKilled() )
//		{
//			entityControl1->getController()->kill();
//			Trigger *trigger = new Trigger;
//			DamageAction* damageAction = new DamageAction(20);
//			trigger->addAction(damageAction);
//			entityControl0->AddTrigger(trigger);
//		}
//	}
//	else if (entityControl1->getName() == "Pingvin" && entityControl0->getName() != "kard")
//	{
//		if ( !entityControl0->getController()->isKilled() )
//		{
//			entityControl0->getController()->kill();
//			Trigger *trigger = new Trigger;
//			DamageAction* damageAction = new DamageAction(20);
//			trigger->addAction(damageAction);
//			entityControl1->AddTrigger(trigger);
//		}
//	}
//	else if (entityControl0->getName() == "kard" && entityControl1->getName() != "Pingvin")
//	{
//		Trigger *trigger = new Trigger;
//		DamageAction* damageAction = new DamageAction(20);
//		trigger->addAction(damageAction);
//		entityControl1->AddTrigger(trigger);
//	}
//	else if (entityControl1->getName() == "kard" && entityControl0->getName() != "Pingvin")
//	{
//		Trigger *trigger = new Trigger;
//		DamageAction* damageAction = new DamageAction(20);
//		trigger->addAction(damageAction);
//		entityControl0->AddTrigger(trigger);
//	}
//
//	return false;
//}


//#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
//#define WIN32_LEAN_AND_MEAN
//#include "windows.h"
//#endif
//
//#ifdef __cplusplus
//extern "C" {
//#endif
//
//#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
//	INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
//#else
//	int main(int argc, char *argv[])
//#endif
//	{
//		// Create application object
//		Game app;
//
//		try {
//			app.go();
//		} catch( Ogre::Exception& e ) {
//#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
//			MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
//#else
//			std::cerr << "An exception has occured: " <<
//				e.getFullDescription().c_str() << std::endl;
//#endif
//		}
//
//		return 0;
//	}
//
//#ifdef __cplusplus
//}
//#endif
